[COCI 2009] OTOCI / 极地旅行社

好久没写lct了

居然还能一发过

#include<cstdio>
#include<iostream>
const int maxn = 100100;
int n,q;
int son[maxn][2],fa[maxn],val[maxn],sum[maxn],tag[maxn];
inline int get(int x,int p=1){return son[fa[x]][p]==x;}
inline int is_root(int x){return !(get(x,0)||get(x));}
inline void up(int x){sum[x]=sum[son[x][0]]+sum[son[x][1]]+val[x];}
inline void down(int x){
    if(tag[x]){
        tag[son[x][0]]^=1,tag[son[x][1]]^=1;
        tag[x]=0,std::swap(son[x][0],son[x][1]);
    }
}
inline void rotate(int x){
    int y=fa[x],z=fa[y],b=get(x);
    if(!is_root(y))son[z][get(y)]=x;
    son[y][b]=son[x][!b],son[x][!b]=y;
    fa[son[y][b]]=y,fa[y]=x,fa[x]=z;
    up(y),up(x);
}
int st[maxn],top;
inline void splay(int x){
    st[top=1]=x;
    for(int y=x;!is_root(y);st[++top]=y=fa[y]);
    for(;top;--top)down(st[top]);
    for(;!is_root(x);rotate(x))
        if(!is_root(fa[x]))rotate(get(x)^get(fa[x])?x:fa[x]);
    up(x);
}
inline void access(int x){
    for(int t=0;x;son[x][1]=t,t=x,x=fa[x])
        splay(x);
}
inline void make_root(int x){
    access(x),splay(x),tag[x]^=1;
}
inline int con(int x,int y){
    make_root(x),access(y),splay(y);
    int now=x;while(fa[now])now=fa[now];
    return now==y;
}
inline void link(int x,int y){
    make_root(x),fa[x]=y;
}
inline int split(int x,int y){
    make_root(x),access(y),splay(y);
    return sum[y];
}
int main(){
    std::ios::sync_with_stdio(false),std::cin.tie(0);
    std::cin >> n;
    for(int i=1;i<=n;++i)std::cin >> val[i],sum[i]=val[i];
    char buf[20];
    std::cin >> q;
    for(int i=1;i<=q;++i){
        int a,b;
        std::cin >> buf >> a >> b;
        if(*buf == 'b'){
            if(con(a,b))std::cout << "no\n";
            else std::cout << "yes\n",link(a,b);
        }
        if(*buf == 'p'){
            make_root(a),val[a]=b,up(a);
        }
        if(*buf == 'e'){
            if(!con(a,b))std::cout << "impossible\n";
            else std::cout << split(a,b) << '\n';
        }
    }
}

猜你喜欢

转载自www.cnblogs.com/skip1978/p/10338475.html