BZOJ - 1036 树的统计Count (LCT)
LCT试炼题(代码量居然完爆树剖?)
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N=3e4+10,inf=0x3f3f3f3f; 4 int fa[N],ch[N][2],flp[N],n,m,sta[N],tp,val[N],sum[N],mx[N],tu[N],tv[N]; 5 bool isrt(int u) {return ch[fa[u]][0]!=u&&ch[fa[u]][1]!=u;} 6 int sf(int u) {return ch[fa[u]][1]==u;} 7 void pu(int u) {sum[u]=sum[ch[u][0]]+sum[ch[u][1]]+val[u],mx[u]=max(max(mx[ch[u][0]],mx[ch[u][1]]),val[u]);} 8 void pd(int u) {if(flp[u])flp[u]=0,flp[ch[u][0]]^=1,flp[ch[u][1]]^=1,swap(ch[u][0],ch[u][1]);} 9 void rot(int u) { 10 int v=fa[u],w=fa[v],f=sf(u); 11 if(!isrt(v))ch[w][sf(v)]=u; 12 ch[v][f]=ch[u][f^1],fa[ch[v][f]]=v; 13 ch[u][f^1]=v,fa[u]=fa[v],fa[v]=u; 14 pu(v); 15 } 16 void splay(int u) { 17 sta[tp=0]=u; 18 for(int v=u; !isrt(v); v=fa[v])sta[++tp]=fa[v]; 19 for(; ~tp; pd(sta[tp--])); 20 for(; !isrt(u); rot(u)) 21 if(!isrt(fa[u])&&sf(fa[u])==sf(u))rot(fa[u]); 22 pu(u); 23 } 24 void access(int u) {for(int v=0; u; u=fa[v=u])splay(u),ch[u][1]=v,pu(u);} 25 void makert(int u) {access(u),splay(u),flp[u]^=1;} 26 void link(int u,int v) {makert(u),fa[u]=v;} 27 void split(int u,int v) {makert(u),access(v),splay(v);} 28 int main() { 29 sum[0]=0,mx[0]=~inf; 30 scanf("%d",&n); 31 for(int i=1; i<n; ++i)scanf("%d%d",&tu[i],&tv[i]); 32 for(int i=1; i<=n; ++i)scanf("%d",&val[i]),mx[i]=sum[i]=val[i]; 33 for(int i=1; i<n; ++i)link(tu[i],tv[i]); 34 scanf("%d",&m); 35 char s[10]; 36 while(m--) { 37 int x,y; 38 scanf("%s%d%d",s,&x,&y); 39 if(s[1]=='S')split(x,y),printf("%d\n",sum[y]); 40 else if(s[1]=='M')split(x,y),printf("%d\n",mx[y]); 41 else if(s[1]=='H')splay(x),val[x]=y,pu(x); 42 } 43 return 0; 44 }