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

题目

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

做法

添边,修改权值,查询链和,为什么有种莫名的熟悉感,水题啊!!!

十分钟打完后调了二十分钟才做完~~Rotate(x)犯了个**错误~~,宁可慢点打也要一遍过

My complete code

#include<cstdio>
#include<cstring>
#include<string>
#include<iostream>
#include<algorithm>
using namespace std;
typedef int LL;
const LL maxn=1e6;
inline LL Read(){
    LL x(0),f(1);char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9')x=(x<<3)+(x<<1)+c-'0',c=getchar();
    return x*f;
}
LL n,m;
LL sum[maxn],son[maxn][2],fa[maxn],val[maxn],sta[maxn],r[maxn];
char s[100];
inline void Update(LL x){
    sum[x]=sum[son[x][0]]+sum[son[x][1]]+val[x];
}
inline bool Notroot(LL x){
    return son[fa[x]][0]==x||son[fa[x]][1]==x;
}
inline void Pushr(LL x){
    swap(son[x][0],son[x][1]),r[x]^=1;
}
inline void Pushdown(LL x){
    if(r[x]){
        if(son[x][0])Pushr(son[x][0]);
        if(son[x][1])Pushr(son[x][1]);
        r[x]=0;
    }
}
inline void Rotate(LL x){
    LL y(fa[x]),z(fa[y]),lz=(son[y][1]==x);
    if(Notroot(y)) son[z][son[z][1]==y]=x;fa[x]=z;
    son[y][lz]=son[x][lz^1];
    if(son[y][lz]) fa[son[y][lz]]=y;
    son[x][lz^1]=y; fa[y]=x;
    Update(y),Update(x);
}
inline void Splay(LL x){
    LL y(x),top(0); sta[++top]=y;
    while(Notroot(y)) sta[++top]=y=fa[y];
    while(top) Pushdown(sta[top--]);
    while(Notroot(x)){
        y=fa[x];
        if(Notroot(y)){
            LL z(fa[y]);
            if(((son[z][1]==y)^(son[y][1]==x))==0) Rotate(y);
            else Rotate(x);
        }Rotate(x);
    }
}
inline void Access(LL x){
    for(LL y=0;x;y=x,x=fa[x])
        Splay(x),son[x][1]=y,Update(x);
}
inline void Makeroot(LL x){
    Access(x),Splay(x),Pushr(x);
}
inline void Split(LL x,LL y){
    Makeroot(x);
    Access(y);
    Splay(y);
}
inline void Link(LL x,LL y){
    Makeroot(x);fa[x]=y;
}
inline LL Findroot(LL x){
    Access(x);
    Splay(x);
    while(son[x][0]) x=son[x][0]; Splay(x);
    return x;
}
int main(){
    n=Read();
    for(LL i=1;i<=n;++i) sum[i]=val[i]=Read();
    m=Read();LL ret(0);
    while(m--){
        scanf(" %s",s);
        LL a(Read()),b(Read());
        if(s[0]=='b'){
            if(Findroot(a)!=Findroot(b)){
                printf("yes\n");
                Link(a,b);
            }else printf("no\n");
        }else if(s[0]=='p'){
            Makeroot(a);
            val[a]=b;
            Update(a);
        }else if(s[0]=='e'){
            if(Findroot(a)!=Findroot(b))
                printf("impossible\n");
            else{
                Split(a,b);
                printf("%d\n",sum[b]);
            }
        }
    }return 0;
}

猜你喜欢

转载自www.cnblogs.com/y2823774827y/p/10328546.html