[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 }