记录编号 408021 评测结果 AAAAAAAAAA
题目名称 [ZJOI 2008]树的统计Count 最终得分 100
用户昵称 Gravatar半汪 是否通过 通过
代码语言 C++ 运行时间 2.925 s
提交时间 2017-05-23 18:32:41 内存使用 1.46 MiB
显示代码纯文本
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=30010;
int son[maxn][2],v[maxn],qsum[maxn],qmax[maxn],tag[maxn],fa[maxn],n,m,s[maxn],top,from[maxn],to[maxn];
#define L(x) son[x][0]
#define R(x) son[x][1]
void check(){
    for(int i=1;i<=n;i++)cout<<i<<" "<<fa[i]<<" "<<L(i)<<" "<<R(i)<<" "<<qmax[i]<<" "<<qsum[i]<<endl;
}
bool isroot(int x){
    if(!fa[x])return 1;
    if(L(fa[x])==x||R(fa[x])==x)return 0;
    return 1;
}
void update(int x){
    if(!x)return ;
    qsum[x]=qsum[L(x)]+qsum[R(x)]+v[x];
    qmax[x]=v[x];
    if(L(x))qmax[x]=max(qmax[x],qmax[L(x)]);
    if(R(x))qmax[x]=max(qmax[x],qmax[R(x)]);
}
void pushdown(int x){
    if(!x||!tag[x])return;
    tag[L(x)]^=1;
    tag[R(x)]^=1;
    swap(L(x),R(x));
   // cout<<x<<" "<<L(x)<<" "<<R(x)<<endl;
    tag[x]=0;
}
void rotate(int x,int k){
    int y=son[x][k^1];
    son[x][k^1]=son[y][k];
    son[y][k]=x;
    fa[son[x][k^1]]=x;
    if(L(fa[x])==x)L(fa[x])=y;
    else if(R(fa[x])==x)R(fa[x])=y;
    fa[y]=fa[x];fa[x]=y;
    update(x);update(y);
   // cout<<"rotate"<<x<<" "<<k<<endl;
}
void splay(int x){
   // cout<<x<<endl;
    s[++top]=x;
    for(int i=x;!isroot(i);i=fa[i])s[++top]=fa[i];
    while(top)pushdown(s[top--]);
    int y,z;
 //   cout<<x<<"!"<<fa[x]<<" "<<R(2)<<" "<<isroot(x)<<endl;
    while(!isroot(x)){
      //  cout<<x<<endl;
        y=fa[x],z=fa[y];
        if(isroot(y))rotate(y,L(y)==x);
        else{
            if((L(y)==x)==(L(z)==y))rotate(z,L(z)==y),rotate(y,L(y)==x);
            else rotate(y,L(y)==x),rotate(z,L(z)==x);
        }
    }update(x);
   // cout<<x<<" * "<<L(x)<<" "<<R(x)<<endl;
} 
void access(int x){
    int y=0;
    while(x){
     //   cout<<x<<" "<<y<<endl;
        splay(x);
        R(x)=y;
        update(x);
        y=x;
        x=fa[x];
    }
}
void makeroot(int x){
    access(x);
  //  cout<<"had accessed"<<endl;
   // check();
  //  cout<<2<<" "<<L(2)<<" "<<R(2)<<" "<<fa[1]<<endl;
    splay(x);
    tag[x]^=1;
}
void link(int x,int y){
 //   cout<<x<<"****"<<y<<endl;
    makeroot(x);
    fa[x]=y;
  //  check();
}
void change(int x,int w){
    splay(x);
    v[x]=w;
    qmax[x]=w;
    qsum[x]=w;
    if(L(x))qmax[x]=max(qmax[L(x)],qmax[x]);
    if(R(x))qmax[x]=max(qmax[R(x)],qmax[x]);
    qsum[x]=w+qsum[L(x)]+qsum[R(x)];
}
void querymax(int x,int y){
    makeroot(x);
    access(y);
    splay(x);
    printf("%d\n",qmax[x]);
}
void querysum(int x,int y){
    makeroot(x);
    access(y);
    splay(x);
    printf("%d\n",qsum[x]);
}
int main(){
    freopen("bzoj_1036.in","r",stdin);freopen("bzoj_1036.out","w",stdout);
  //  freopen("1036.in","r",stdin);freopen("1036.out","w",stdout);
    scanf("%d",&n);
    for(int i=1;i<n;i++){
        int x,y;
        scanf("%d%d",&x,&y);
        from[i]=x;
        to[i]=y;
    }
    for(int i=1;i<=n;i++)scanf("%d",&v[i]);
    for(int i=1;i<n;i++){
        link(from[i],to[i]);
    }
//    for(int i=1;i<=n;i++)cout<<i<<" "<<fa[i]<<" "<<L(i)<<" "<<R(i)<<" "<<qmax[i]<<" "<<qsum[i]<<endl;
    scanf("%d",&m);
    while(m--){
        char ch[10];
        scanf("%s",ch);
        if(ch[0]=='C'){
            int u,t;
            scanf("%d%d",&u,&t);
            change(u,t);
        }
        if(ch[1]=='M'){
            int u,v;
            scanf("%d%d",&u,&v);
            querymax(u,v);
        }
        if(ch[1]=='S'){
            int u,v;
            scanf("%d%d",&u,&v);
            querysum(u,v);
        }
    }
    return 0;
}