JZOJ 5107. 【GDSOI2017】 中学生数据结构题
生活随笔
收集整理的這篇文章主要介紹了
JZOJ 5107. 【GDSOI2017】 中学生数据结构题
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
Description
Input
第一行有一個整數 N,表示 S 國城市的數量。
接下來有 N-1 行,每行兩個數 u,v 表示一條道路。
第 N+1 行為一個整數 Q,表示接下來有 Q 個操作。
接下來有 Q 行,每行表示一個操作,格式如題目描述所示。
Output
對于每一個 QUERY 操作,輸出一個數,表示詢問的當前編號為 X 和編號為 Y 的城市的最短路徑間的城市 (包括編號為 X 的城市和編號為 Y 的城市)的士兵總和。Sample Input
Sample Input1:
5
1 2
1 3
3 4
3 5
6
ADD 1 5 2
ADD 3 4 1
QUERY 1 4
SHIFT 1 4
ADD 5 4 1
QUERY 4 5
Sample Input12:
5
1 2
2 3
3 4
4 5
5
ADD 1 3 2
ADD 3 5 1
SHIFT 2 4
QUERY 1 3
QUERY 1 5
Sample Output
Sample Output1:
6
10
Sample Output2:
5
9
Data Constraint
Solution
-
剛了這么久終于過了……
-
還是套路,一棵形態LCT,維護的是當前樹的形態;
-
一個權值LCT(Splay),維護的是當前形態下形態LCT中每個點對應的權值。
-
按要求操作即可,時間復雜度 O(nlogn)O(n\ log\ n)O(n?log?n)。
Code
#include<cstdio> #include<algorithm> #include<cctype> using namespace std; typedef long long LL; const int N=1e5+5; int tot,top; int first[N],nex[N<<1],en[N<<1]; int st[N]; char ty[7]; struct value {int fa[N],s[N][2],size[N];LL key[N],sum[N],tag[N];bool rev[N];inline bool pd(int x){return x==s[fa[x]][1];}inline void update(int x){size[x]=size[s[x][0]]+size[s[x][1]]+1;sum[x]=sum[s[x][0]]+sum[s[x][1]]+key[x];}inline void reverse(int x){if(x) swap(s[x][0],s[x][1]),rev[x]^=1;}inline void modify(int x,LL val){if(x){sum[x]+=size[x]*val;key[x]+=val;tag[x]+=val;}}inline void down(int x){if(rev[x]){rev[x]=false;reverse(s[x][0]);reverse(s[x][1]);}if(tag[x]){modify(s[x][0],tag[x]);modify(s[x][1],tag[x]);tag[x]=0;}}inline void rotate(int x){down(x);int y=fa[x],w=pd(x);if(fa[x]=fa[y]) s[fa[y]][pd(y)]=x;if(s[y][w]=s[x][w^1]) fa[s[y][w]]=y;s[fa[y]=x][w^1]=y;update(y);}inline void splay(int x){for(int y;y=fa[x];rotate(x))if(fa[y]) rotate(pd(x)==pd(y)?y:x);update(x);}inline int root(int x){while(fa[x]) x=fa[x];return x;}int kth(int x,int k){down(x);if(size[s[x][0]]+1==k) return x;if(size[s[x][0]]+1>k) return kth(s[x][0],k);return kth(s[x][1],k-size[s[x][0]]-1);} }v; struct shape {int fa[N],s[N][2],size[N],rt[N];bool rev[N];inline bool pd(int x){return x==s[fa[x]][1];}inline bool isroot(int x){return s[fa[x]][0]^x && s[fa[x]][1]^x;}inline void reverse(int x){if(x) swap(s[x][0],s[x][1]),rev[x]^=1;}inline void update(int x){size[x]=size[s[x][0]]+size[s[x][1]]+1;}inline void down(int x){if(rev[x]){rev[x]=false;reverse(s[x][0]);reverse(s[x][1]);}}inline void rotate(int x){int y=fa[x],w=pd(x);if((fa[x]=fa[y]) && !isroot(y)) s[fa[y]][pd(y)]=x;if(s[y][w]=s[x][w^1]) fa[s[y][w]]=y;s[fa[y]=x][w^1]=y;rt[x]=rt[y],rt[y]=0;update(y);}inline void splay(int x){for(int y=st[top=1]=x;!isroot(y);y=fa[y]) st[++top]=fa[y];while(top) down(st[top--]);for(int y;!isroot(x);rotate(x))if(!isroot(y=fa[x])) rotate(pd(x)==pd(y)?y:x);update(x);}inline void access(int x){for(int y=0;x;x=fa[y=x]){splay(x);int xx=v.root(rt[x]);xx=v.kth(xx,size[s[x][0]]+1);v.splay(rt[x]=xx);if(s[x][1]){rt[s[x][1]]=v.s[xx][1];v.fa[v.s[xx][1]]=0;v.s[xx][1]=s[x][1]=0;}if(y){s[x][1]=y;v.s[xx][1]=v.root(rt[y]);if(v.s[xx][1]) v.fa[v.s[xx][1]]=xx;}v.update(xx);update(x);}}inline void mkroot(int x){access(x),splay(x),reverse(x);int xx=v.root(rt[x]);xx=v.kth(xx,size[s[x][0]]+1);v.splay(xx);v.reverse(xx);} }s; inline int read() {int X=0,w=0; char ch=0;while(!isdigit(ch)) w|=ch=='-',ch=getchar();while(isdigit(ch)) X=(X<<3)+(X<<1)+(ch^48),ch=getchar();return w?-X:X; } inline void insert(int x,int y) {nex[++tot]=first[x];first[x]=tot;en[tot]=y; } void dfs(int x,int y) {s.fa[x]=y;s.size[x]=v.size[x]=1;s.rt[x]=x;for(int i=first[x];i;i=nex[i])if(en[i]^y) dfs(en[i],x); } int main() {freopen("shift.in","r",stdin);freopen("shift.out","w",stdout);int n=read();for(int i=1;i<n;i++){int x=read(),y=read();insert(x,y);insert(y,x);}dfs(1,0);int q=read();while(q--){scanf("%s",&ty);int x=read(),y=read();if(ty[0]=='S' && x==y) continue;s.mkroot(x);s.access(y);s.splay(y);int yy=s.rt[y];v.splay(yy);yy=v.kth(yy,s.size[s.s[y][0]]+1);v.splay(yy);if(ty[0]=='A'){int z=read();v.modify(yy,z);}elseif(ty[0]=='S'){int pos=v.s[yy][0];v.s[yy][0]=0;v.fa[pos]=0;pos=v.kth(pos,1);v.splay(pos);v.fa[pos]=yy;v.s[yy][1]=pos;v.update(yy);}elseprintf("%lld\n",v.sum[yy]);}return 0; }總結
以上是生活随笔為你收集整理的JZOJ 5107. 【GDSOI2017】 中学生数据结构题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JZOJ 5982. 【WC2019模拟
- 下一篇: JZOJ 5987. 【WC2019模拟