HYSBZ/BZOJ 1036 [ZJOI2008] 树的统计Count - 动态树LCT

题目描述

看着就是个LCT的模板题,可惜忘记在change的时候Update了,最终爆零!悲惨经历,教训啊。

题目有坑
1. 有负数,要么最开始全部赋值为-INF,否则要判断儿子是否为0
2. Link之后要Update,Change之后要Update,Rotate之后要Update,Splay之后要Update,Access要Update.
3. Access之后不要忘了Splay(u),Splay之前不要忘了Push_up()

#include<cstdio>
#include<algorithm>
using namespace std;
#define MAXN 30000

struct node{
    int ch[2],fa,path_fa;
    int flip,mx,sum;
}tre[MAXN+10];

int n,wt[MAXN+10],l[MAXN+10][3];
char s[20];

void Push_down(int u)
{
    if(!tre[u].flip)
        return ;
    tre[u].flip=0;
    swap(tre[u].ch[0],tre[u].ch[1]);
    if(tre[u].ch[0])
        tre[tre[u].ch[0]].flip^=1;
    if(tre[u].ch[1])
        tre[tre[u].ch[1]].flip^=1;
}
void Push_up(int x)
{
    if(tre[x].fa)
        Push_up(tre[x].fa);
    Push_down(x);
}
void Update(int u)
{
    if(!u) return ;
    tre[u].mx=tre[u].sum=wt[u];
    if(tre[u].ch[0]){
        tre[u].mx=max(tre[u].mx,tre[tre[u].ch[0]].mx);
        tre[u].sum+=tre[tre[u].ch[0]].sum;
    }
    if(tre[u].ch[1]){
        tre[u].mx=max(tre[u].mx,tre[tre[u].ch[1]].mx);
        tre[u].sum+=tre[tre[u].ch[1]].sum;
    }
}
void Rotate(int x,int d) //RotateRight d=1 RotateLeft d=0
{
    int y=tre[x].fa,fa=tre[y].fa;
    tre[y].ch[d^1]=tre[x].ch[d];
    if(tre[x].ch[d])
        tre[tre[x].ch[d]].fa=y;
    tre[x].ch[d]=y,tre[y].fa=x;
    tre[x].fa=fa;
    if(fa){
        if(y==tre[fa].ch[0]) tre[fa].ch[0]=x;
        else tre[fa].ch[1]=x;
    }
    tre[x].path_fa=tre[y].path_fa;
    tre[y].path_fa=0;
    Update(y);
}
void Splay(int x)
{
    Push_up(x);
    while(!tre[x].path_fa&&tre[x].fa){
        int y=tre[x].fa,z=tre[y].fa;
        if(tre[y].path_fa||!tre[y].fa){
            if(x==tre[y].ch[0]) Rotate(x,1);
            else Rotate(x,0);
        }
        else{
            if(y==tre[z].ch[0]){
                if(x==tre[y].ch[0])
                    Rotate(y,1),Rotate(x,1);
                else
                    Rotate(x,0),Rotate(x,1);
            }
            else{
                if(x==tre[y].ch[0])
                    Rotate(x,1),Rotate(x,0);
                else
                    Rotate(y,0),Rotate(x,0);
            }
        }
    }
    Update(x);
}
void Access(int u)
{
    int x=u,y=0;
    while(x){
        Splay(x);
        int v=tre[x].ch[1];
        if(v){
            tre[v].fa=0;
            tre[v].path_fa=x;
        }
        tre[x].ch[1]=y;
        if(y){
            tre[y].path_fa=0;
            tre[y].fa=x;
        }
        Update(x);
        y=x;
        x=tre[y].path_fa;
    }
    Splay(u);
}
void Link(int x,int y)
{
    Access(x);
    Access(y);
    tre[x].flip^=1;
    tre[y].ch[1]=x;
    tre[x].fa=y,tre[x].path_fa=0;
    Update(y);
}
void Quary(int a,int b,int &q1,int &q2)
{
    Access(a);
    int x=b,y=0;
    while(x){
        Splay(x);
        if(!tre[x].path_fa){
            q1=q2=wt[x];
            if(tre[x].ch[1]){
                q1=max(tre[tre[x].ch[1]].mx,q1);
                q2+=tre[tre[x].ch[1]].sum;
            }
            if(y){
                q1=max(q1,tre[y].mx);
                q2+=tre[y].sum;
            }
            return ;
        }
        int v=tre[x].ch[1];
        if(v){
            tre[v].fa=0;
            tre[v].path_fa=x;
        }
        tre[x].ch[1]=y;
        if(y){
            tre[y].fa=x;
            tre[y].path_fa=0;
        }
        Update(x);
        y=x;
        x=tre[y].path_fa;
    }
}
int main()
{
    //freopen("count.in","r",stdin);
    //freopen("count.out","w",stdout);

    int x,y;
    scanf("%d",&n);
    for(int i=1;i<n;i++)
        scanf("%d%d",&l[i][0],&l[i][1]);
    for(int i=1;i<=n;i++){
        scanf("%d",&wt[i]);
        tre[i].mx=tre[i].sum=wt[i];
    }
    for(int i=1;i<n;i++)
        Link(l[i][0],l[i][1]);
    int Q,q1,q2;
    scanf("%d",&Q);
    while(Q--){
        scanf("%s%d%d",s,&x,&y);
        if(s[0]=='C'){
            Access(x);
            wt[x]=y;
            Update(x);
        }
        else if(s[1]=='M'){
            Quary(x,y,q1,q2);
            printf("%d\n",q1);
        }
        else{
            Quary(x,y,q1,q2);
            printf("%d\n",q2);
        }
    }
}
posted @ 2016-02-04 15:03  KatarinaYuan  阅读(120)  评论(0编辑  收藏  举报