zoukankan      html  css  js  c++  java
  • bzoj2733

    1.treap

    每个点建一棵treap,维护优先级,然后启发式合并两棵treap

    #include<cstdio>
    #include<cctype>
    #include<algorithm>
    #define maxn 100002
    using namespace std;
    int rt[maxn],fa[maxn],n,m,q;
    struct data{int l,r,rnd,siz,key;data(){siz=1;l=r=rnd=0;}}tr[maxn];
    int findfa(int x){if(fa[x]==x)return x;return fa[x]=findfa(fa[x]);}
    void read(int &x){
        char ch=getchar();x=0;int f=1;
        while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
        while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
        x*=f;
    }
    void rturn(int &x){int tmp=tr[x].l;tr[x].l=tr[tmp].r;tr[tmp].r=x;tr[tmp].siz=tr[x].siz;tr[x].siz=tr[tr[x].l].siz+1+tr[tr[x].r].siz;x=tmp;}
    void lturn(int &x){int tmp=tr[x].r;tr[x].r=tr[tmp].l;tr[tmp].l=x;tr[tmp].siz=tr[x].siz;tr[x].siz=tr[tr[x].l].siz+1+tr[tr[x].r].siz;x=tmp;}
    void insert(int &rt,int x){
        if(!rt){rt=x;tr[x].rnd=rand();return;}
        tr[rt].siz++;
        if(tr[x].key<tr[rt].key){
            insert(tr[rt].l,x);
            if(tr[tr[rt].l].rnd<tr[rt].rnd)rturn(rt);
        }else{
            insert(tr[rt].r,x);
            if(tr[tr[rt].r],x);
            if(tr[tr[rt].r].rnd<tr[rt].rnd)lturn(rt);
        }
    }
    void merge_node(int x,int y){
        if(!y)return;
        merge_node(x,tr[y].l);
        merge_node(x,tr[y].r);
        insert(x,y);
    }
    void merge(int x,int y){
        int fx=findfa(x),fy=findfa(y);
        if(fx==fy)return;
        if(tr[fx].siz<tr[fy].siz)swap(fx,fy);
        fa[fy]=fx;
        merge_node(fx,fy);
    }
    int getkth(int x,int k){
        if(k<=tr[tr[x].l].siz)return getkth(tr[x].l,k);
        k-=tr[tr[x].l].siz+1;
        if(k==0)return x;
        return getkth(tr[x].r,k);
    }
    int main(){
        int a,b;tr[0].siz=0;
        read(n);read(m);
        for(int i=1;i<=n;i++)read(tr[i].key),fa[i]=i;
        for(int i=1;i<=m;i++){read(a);read(b);merge(a,b);}
        read(q);
        char cc;
        while(q--){
            scanf(" %c",&cc);read(a);read(b);
            if(cc=='Q'){a=findfa(a);if(tr[a].siz<b)printf("-1
    ");else printf("%d
    ",getkth(a,b));}else merge(a,b);
        }
    }

     2.splay

    #include<cstdio>
    #include<cctype>
    #include<algorithm>
    #define maxn 100002
    using namespace std;
    int n,m,q,rt[maxn],f[maxn],father[maxn],key[maxn],pos[maxn],siz[maxn],tr[maxn][2];
    void read(int &x){
        char ch=getchar();x=0;int f=1;
        while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
        while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
        x*=f;
    }
    int findfa(int x){
        if(f[x]==x)return x;return f[x]=findfa(f[x]);
    }
    inline void rotate(int x,int &rt){
        int fa=father[x],gfa=father[fa];int whicx=(tr[fa][1]==x);
        if(fa==rt)rt=x; else tr[gfa][(tr[gfa][1]==fa)]=x;
        father[x]=gfa; father[fa]=x;
        tr[fa][whicx]=tr[x][whicx^1]; father[tr[x][whicx^1]]=fa; tr[x][whicx^1]=fa;
        siz[fa]=siz[tr[fa][0]]+siz[tr[fa][1]]+1;
        siz[x]=siz[tr[x][0]]+siz[tr[x][1]]+1;
    }
    void splay(int x,int &rt){
        for(int y;y=father[x];rotate(x,rt))
           if(father[y])rotate((x==tr[y][0])==(y==tr[father[y]][0])?y:x,rt);
    }
    void insert(int x,int &rt,int ff){
        if(!rt){rt=x;father[x]=ff;return;}
        siz[rt]++;
        if(key[x]<key[rt])insert(x,tr[rt][0],rt);
        else insert(x,tr[rt][1],rt);
    }
    void merge_node(int x,int y){
        if(!x)return;
        if(tr[x][0])merge_node(tr[x][0],y);
        if(tr[x][1])merge_node(tr[x][1],y);
        insert(x,rt[y],0);
        splay(x,rt[y]);
    }
    void merge(int a,int b){
        int fta=findfa(a),ftb=findfa(b);
        if(fta==ftb)return;
        if(siz[rt[fta]]>siz[rt[ftb]])swap(fta,ftb);
        f[fta]=ftb;
        merge_node(rt[fta],ftb);
    }
    int query(int rt,int k){
        int u=rt;
        while(1){
            if(k<=siz[tr[u][0]])u=tr[u][0];
            else if(siz[tr[u][0]]+1==k)return key[u];
            else k-=siz[tr[u][0]]+1,u=tr[u][1];
        }
    }
    int main(){
        read(n);read(m);
        int a,b;
        for(int i=1;i<=n;i++){read(key[i]);pos[key[i]]=i;rt[i]=i;f[i]=i;siz[i]=1;}
        for(int i=1;i<=m;i++){read(a);read(b);merge(a,b);}
        int q;char ch;read(q);
        while(q--){
            scanf(" %c",&ch);read(a);read(b);
            if(ch=='Q'){if(siz[rt[findfa(a)]]<b)printf("-1
    ");else printf("%d
    ",pos[query(rt[findfa(a)],b)]);}
            else merge(a,b);
        }
    }
  • 相关阅读:
    poj 3243 Clever Y(BabyStep GiantStep)
    poj 2417 Discrete Logging
    poj 3481 Double Queue
    hdu 4046 Panda
    hdu 2896 病毒侵袭
    poj 1442 Black Box
    hdu 2815 Mod Tree
    hdu 3065 病毒侵袭持续中
    hdu 1576 A/B
    所有控件
  • 原文地址:https://www.cnblogs.com/MikuKnight/p/9059286.html
Copyright © 2011-2022 走看看