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 }

 

posted @ 2019-06-22 15:33  jrltx  阅读(178)  评论(0编辑  收藏  举报