bzoj 1036: [ZJOI2008]树的统计Count动态树
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<queue> 6 using namespace std; 7 #define maxn 60500 8 #define inf 0x3fffffff 9 int ch[maxn][2]; 10 int s[maxn],ma[maxn],val[maxn],pre[maxn],rt[maxn]; 11 int n,nn; 12 int e[maxn],ne[maxn*2],f[maxn],v[maxn*2]; 13 void add(int x,int y){ 14 ne[++nn]=e[x],e[x]=nn,v[nn]=y; 15 } 16 void up(int x){ 17 s[x]=val[x]+s[ch[x][0]]+s[ch[x][1]]; 18 ma[x]=max(val[x],max(ma[ch[x][0]],ma[ch[x][1]])); 19 } 20 void rotate(int x){ 21 int y=pre[x],z=pre[y],k=ch[y][0]==x; 22 pre[ch[y][!k]=ch[x][k]]=y; 23 pre[ch[x][k]=y]=x; 24 pre[x]=z; 25 if(rt[y])rt[x]=1,rt[y]=0; 26 else ch[z][ch[z][1]==y]=x; 27 up(y); 28 } 29 void splay(int x){ 30 for(;!rt[x];){ 31 int y=pre[x],z=pre[y]; 32 if(rt[y])rotate(x); 33 else if((ch[y][1]==x)==(ch[z][1]==y))rotate(y),rotate(x); 34 else rotate(x),rotate(x); 35 } 36 up(x); 37 } 38 int acess(int x){ 39 int y=0; 40 for(;x;y=x,x=pre[x]){ 41 splay(x); 42 rt[ch[x][1]]=1; 43 ch[x][1]=y; 44 rt[y]=0; 45 up(x); 46 } 47 return y; 48 } 49 int sum(int a,int b){ 50 acess(a); 51 int z=acess(b); 52 if(z==a)return s[ch[a][1]]+val[a]; 53 splay(a); 54 return s[a]+s[ch[z][1]]+val[z]; 55 } 56 int MAX(int a,int b){ 57 acess(a); 58 int z=acess(b); 59 if(z==a)return max(ma[ch[a][1]],val[a]); 60 splay(a); 61 return max(val[z],max(ma[a],ma[ch[z][1]])); 62 } 63 void change(int a,int b){ 64 splay(a); 65 val[a]=b; 66 up(a); 67 } 68 char in[10]; 69 int main(){ 70 scanf("%d",&n); 71 int x,a,b; 72 for(int i=1;i<n;i++){ 73 scanf("%d%d",&a,&b); 74 add(a,b); 75 add(b,a); 76 } 77 queue<int> jj; 78 jj.push(1); 79 while(!jj.empty()){ 80 x=jj.front(); 81 jj.pop(); 82 for(int i=e[x];i;i=ne[i]){ 83 if(v[i]==pre[x])continue; 84 pre[v[i]]=x; 85 jj.push(v[i]); 86 } 87 } 88 ma[0]=-inf; 89 for(int i=1;i<=n;i++){ 90 scanf("%d",&a); 91 val[i]=s[i]=ma[i]=a; 92 rt[i]=1; 93 } 94 int q; 95 scanf("%d",&q); 96 for(int i=1;i<=q;i++){ 97 scanf("%s",&in); 98 scanf("%d%d",&a,&b); 99 if(in[1]=='M')printf("%d\n",MAX(a,b)); 100 if(in[1]=='S')printf("%d\n",sum(a,b)); 101 if(in[1]=='H')change(a,b); 102 } 103 } 104