bzoj2733: [HNOI2012]永无乡

spaly.

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn = 100000 + 10;
int n,m,q;
char op[10];

struct Splay {
    int f[maxn],l[maxn],r[maxn],s[maxn],a[maxn],fa[maxn];
    int root;
    
    int find(int x) {
        return fa[x]==x? x : fa[x]=find(fa[x]);
    }
    
    void update(int x) {
        s[x]=s[l[x]]+s[r[x]]+1;
    }
    
    void lr(int x) {
        int y=f[x];
        r[y]=l[x];
        if(l[x]) f[l[x]]=y;
        f[x]=f[y];
        if(f[y]) {
            if(l[f[y]]==y) l[f[y]]=x;
            else r[f[y]]=x;    
        }
        f[y]=x; l[x]=y;
        update(y); update(x);
    }
    
    void rr(int x) {
        int y=f[x];
        l[y]=r[x];
        if(r[x]) f[r[x]]=y;
        f[x]=f[y];
        if(f[y]) {
            if(l[f[y]]==y) l[f[y]]=x;
            else r[f[y]]=x;
        }
        f[y]=x; r[x]=y;
        update(y); update(x);
    }
    
    void rotate(int x) {
        if(l[f[x]]==x) rr(x);
        else lr(x);    
    }
    
    void splay(int x) {
        while(f[x]) {
            if(!f[f[x]]) rotate(x);
            else if((l[f[x]]==x) == (l[f[f[x]]]==f[x])) rotate(f[x]),rotate(x);
            else rotate(x),rotate(x);
        }
    }
    
    void insert(int x,int y) {
        while(true) {
            if(a[y]<=a[x]) {
                if(!l[x]) {
                    l[x]=y,f[y]=x;
                    break;    
                }
                x=l[x];
            }
            else {
                if(!r[x]) {
                    r[x]=y,f[y]=x;
                    break;
                }
                x=r[x];
            }
        }    
        splay(y);
    }
    
    void merge(int x,int y) {
        if(!y) return;
        merge(x,l[y]);
        merge(x,r[y]);    
        l[y]=r[y]=0; s[y]=1;
        insert(x,y);
    }
    
    void Q(int x,int k) {
        splay(x); 
        if(s[x]<k) {
            printf("-1\n");
            return;    
        }
        
        while(s[l[x]]+1 != k) {
            //printf("ddd\n");
            if(s[l[x]]+1>k) x=l[x];
            else {
                k-=s[l[x]]+1;
                x=r[x];
            }
        }
        printf("%d\n",x);
    }
    
    void B(int x,int y) {
        int rx=find(x),ry=find(y);
        
        if(rx!=ry) {
            fa[rx]=ry;    
            splay(x); splay(y);
            if(s[x]<s[y]) swap(x,y);
            merge(x,y);
        }
    }
    
    void init(int n,int m) {
        for(int i=1;i<=n;i++) scanf("%d",&a[i]),fa[i]=i,s[i]=1;
        for(int i=1,u,v;i<=m;i++) scanf("%d%d",&u,&v),B(u,v);
    }
} islands;

int main() {
    scanf("%d%d",&n,&m);
    islands.init(n,m);
    scanf("%d",&q);
    for(int i=1,a,b;i<=q;i++) {
        scanf("%s%d%d",op,&a,&b);
        if(op[0]=='Q') islands.Q(a,b);
        else islands.B(a,b);
    }
    return 0;
}
posted @ 2016-04-30 11:08  invoid  阅读(165)  评论(0编辑  收藏  举报