[CodeChef-ANUDTQ] Dynamic Trees and Queries

类似维护括号序列,给每个点建两个点,然后所有操作都能轻松支持了。注意sum和lastans是long long。

 1 #include<cstdio>
 2 #include<algorithm>
 3 #define rep(i,l,r) for (int i=(l); i<=(r); i++)
 4 #define For(i,x) for (int i=h[x],k; i; i=nxt[i])
 5 typedef long long ll;
 6 using namespace std;
 7 
 8 const int N=400010;
 9 ll ans,sm[N];
10 int n,nd,tim,rt,op,x,y,m,cnt,a[N],tag[N];
11 int v[N],f[N],L[N],R[N],sz[N],c[N][2],h[N],to[N],nxt[N];
12 
13 void add(int u,int v){ to[++cnt]=v; nxt[cnt]=h[u]; h[u]=cnt; }
14 
15 void dfs(int x,int fa){
16     L[x]=++tim; v[tim]=a[x];
17     For(i,x) if ((k=to[i])!=fa) dfs(k,x);
18     R[x]=++tim; v[tim]=a[x];
19 }
20 
21 void upd(int x){
22     sm[x]=sm[c[x][0]]+sm[c[x][1]]+v[x];
23     sz[x]=sz[c[x][0]]+sz[c[x][1]]+1;
24 }
25 
26 void put(int x,int k){ v[x]+=k; sm[x]+=1ll*k*sz[x]; tag[x]+=k; }
27 
28 void push(int x){
29     if (!tag[x]) return;
30     if (c[x][0]) put(c[x][0],tag[x]);
31     if (c[x][1]) put(c[x][1],tag[x]);
32     tag[x]=0;
33 }
34 
35 void pd(int x){ if (f[x]) pd(f[x]); push(x); }
36 
37 int build(int l,int r){
38     int mid=(l+r)>>1,x=mid;
39     if (l<mid) c[x][0]=build(l,mid-1),f[c[x][0]]=x;
40     if (mid<r) c[x][1]=build(mid+1,r),f[c[x][1]]=x;
41     upd(x); return x;
42 }
43 
44 void rot(int &rt,int x){
45     int y=f[x],z=f[y],w=c[y][1]==x;
46     if (y==rt) rt=x; else c[z][c[z][1]==y]=x;
47     f[x]=z; f[y]=x; f[c[x][w^1]]=y; c[y][w]=c[x][w^1];
48     c[x][w^1]=y; upd(y);
49 }
50 
51 void splay(int &rt,int x){
52     for (pd(x); x!=rt; rot(rt,x)){
53         int y=f[x],z=f[y];
54         if (y!=rt) (c[z][0]==y)^(c[y][0]==x) ? rot(rt,x) : rot(rt,y);
55     }
56     upd(x);
57 }
58 
59 int pre(int x){ splay(rt,x); for (x=c[x][0]; c[x][1]; x=c[x][1]); return x; }
60 int lst(int x){ splay(rt,x); for (x=c[x][1]; c[x][0]; x=c[x][0]); return x; }
61 
62 void Ins(int x,int y){
63     int k=lst(L[x]); splay(rt,L[x]); splay(c[rt][1],k);
64     c[k][0]=++nd; v[nd]=y; f[nd]=k; R[++n]=nd;
65     nd++; c[nd-1][0]=nd; v[nd]=y; f[nd]=nd-1; L[n]=nd;
66     upd(nd); upd(nd-1); upd(k); upd(rt);
67 }
68 
69 void Add(int x,int y){
70     int l=pre(L[x]),r=lst(R[x]); splay(rt,l); splay(c[rt][1],r);
71     put(c[r][0],y); upd(r); upd(rt);
72 }
73 
74 void Del(int x){
75     int l=pre(L[x]),r=lst(R[x]); splay(rt,l); splay(c[rt][1],r);
76     c[r][0]=f[c[r][0]]=0; upd(r); upd(rt);
77 }
78 
79 ll Que(int x){ int l=pre(L[x]),r=lst(R[x]); splay(rt,l); splay(c[rt][1],r); return sm[c[r][0]]; }
80 
81 int main(){
82     freopen("anudtq.in","r",stdin);
83     freopen("anudtq.out","w",stdout);
84     scanf("%d",&n);
85     rep(i,1,n) scanf("%d",&a[i]);
86     rep(i,2,n) scanf("%d%d",&x,&y),x++,y++,add(x,y),add(y,x);
87     tim=1; dfs(1,0); rt=build(1,tim+1); nd=tim+1; scanf("%d",&m);
88     rep(i,1,m){
89         scanf("%d%d",&op,&x); x+=ans+1;
90         if (op==1) scanf("%d",&y),Ins(x,y);
91         if (op==2) scanf("%d",&y),Add(x,y);
92         if (op==3) Del(x);
93         if (op==4) printf("%lld\n",ans=Que(x)/2);
94     }
95     return 0;
96 }

 

posted @ 2019-06-09 09:17  HocRiser  阅读(183)  评论(0编辑  收藏  举报