P4312 [COCI 2009] OTOCI / 极地旅行社

思路

LCT维护和的板子
注意findroot的时候要先access一下,修改点权之前要先splay到根

代码

#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
struct Node{
    int fa,son[2],sum,val,inv;
}SPT[600000];
int n,q;
bool isrl(int o){
    return o==SPT[SPT[o].fa].son[1];
}
bool isroot(int o){
    return o!=SPT[SPT[o].fa].son[0]&&o!=SPT[SPT[o].fa].son[1];
}
void pushup(int o){
    SPT[o].sum=SPT[o].val+SPT[SPT[o].son[0]].sum+SPT[SPT[o].son[1]].sum;
}
void pushdown(int o){
    if(SPT[o].inv){
        SPT[SPT[o].son[0]].inv^=1;
        SPT[SPT[o].son[1]].inv^=1;
        swap(SPT[o].son[0],SPT[o].son[1]);
        SPT[o].inv=0;
    }
}
void rorate(int o){
    if(isroot(o))
        return;
    int f=SPT[o].fa;
    int g=SPT[f].fa;
    int which=isrl(o);
    pushdown(f);
    pushdown(o);
    if(!isroot(f))
        SPT[g].son[SPT[g].son[1]==f]=o;
    SPT[o].fa=g;
    SPT[f].son[which]=SPT[o].son[which^1];
    SPT[SPT[o].son[which^1]].fa=f;
    SPT[o].son[which^1]=f;
    SPT[f].fa=o;
    pushup(f);
    pushup(o);
}
void allpush(int o){
    if(!isroot(o))
        allpush(SPT[o].fa);
    pushdown(o);
}
void splay(int o){
    allpush(o);
    for(int f;!isroot(o);rorate(o)){
        if(!isroot(f=SPT[o].fa))
            rorate((isrl(f)==isrl(o))?f:o);
    }
}
void access(int o){
    for(int y=0;o;o=SPT[y=o].fa)
        splay(o),SPT[o].son[1]=y,pushup(o);
}
void makeroot(int o){
    access(o);
    splay(o);
    SPT[o].inv^=1;
    pushdown(o);
}
int findroot(int o,int islink=0){
    access(o);
    splay(o);
    pushdown(o);
    while(SPT[o].son[0])
        pushdown(o=SPT[o].son[0]);
    return o;
}
bool link(int x,int y){
    makeroot(x);
    if(findroot(y,1)!=x){
        SPT[x].fa=y;
        return true;
    }
    return false;
}
int split(int x,int y){
    makeroot(x);
    access(y);
    splay(y);
    return y;
}
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%d",&SPT[i].val);
    scanf("%d",&q);
    char opt[20];
    int x,y;
    for(int i=1;i<=q;i++){
        scanf("%s %d %d",opt,&x,&y);
        if(opt[0]=='b'){
            if(link(x,y))
                printf("yes\n");
            else
                printf("no\n");
        }
        else if(opt[0]=='p'){
            splay(x);
            SPT[x].val=y;
        }
        else{
            if(findroot(x)!=findroot(y)){
                printf("impossible\n");
            }
            else{
                int t=split(x,y);
                printf("%d\n",SPT[t].sum);
            }
        }
    }
    return 0;    
}
posted @ 2019-04-02 12:18  dreagonm  阅读(130)  评论(0编辑  收藏  举报