• 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);
        }
    }
  • 相关阅读:
    从温设计模式
    php pdf转图片
    PHP 微服务集群搭建
    死磕nginx系列--nginx 限流配置
    分别
    一生悲哀
    三十男人的思考
    test markdown
    linux 系统内核空间与用户空间通信的实现与分析<转>
    ue4 SNew补遗
  • 原文地址:https://www.cnblogs.com/MikuKnight/p/9059286.html
Copyright © 2020-2023  润新知