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     

 

 

posted @ 2014-04-11 19:07  wangyucheng  阅读(159)  评论(0编辑  收藏  举报