zoukankan      html  css  js  c++  java
  • P3224 [HNOI2012]永无乡

    思路

    平衡树+启发式合并

    貌似也可以线段树合并

    连边就是合并两个Treap,查询就是第k大

    使用Treap,好写好调

    代码

    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <queue>
    using namespace std;
    int Nodecnt=0,root[100100*2],fa[100100*2],n,m,w_p[100100*2];
    struct Node{
        int lson,rson,sz,val,ran,num;
    }Treap[100100*2];
    int find(int x){
        if(fa[x]==x)
            return x;
        else
            return fa[x]=find(fa[x]);
    }
    queue<int> q;
    void throwin(int x){
        q.push(x);
    }
    int getnew(int val,int num){
        int o;
        if(q.size())
            o=q.front(),q.pop();
        else
            o=++Nodecnt;
        Treap[o].lson=Treap[o].rson=0;
        Treap[o].sz=1;
        Treap[o].ran=rand();
        Treap[o].val=val;
        Treap[o].num=num;
        return o;
    }
    void pushup(int o){
        Treap[o].sz=Treap[Treap[o].lson].sz+Treap[Treap[o].rson].sz+1;
    }
    void rorateL(int &o){
        int x=Treap[o].rson;
        Treap[o].rson=Treap[x].lson;
        Treap[x].lson=o;
        pushup(o);
        pushup(x);
        o=x;
    }
    void rorateR(int &o){
        int x=Treap[o].lson;
        Treap[o].lson=Treap[x].rson;
        Treap[x].rson=o;
        pushup(o);
        pushup(x);
        o=x;
    }
    void insert(int val,int num,int &o){
        if(!o){
            o=getnew(val,num);
            return;
        }
        Treap[o].sz++;
        if(val<=Treap[o].val){
            insert(val,num,Treap[o].lson);
            if(Treap[Treap[o].lson].ran<Treap[o].ran)
                rorateR(o);
        }
        else{
            insert(val,num,Treap[o].rson);
            if(Treap[Treap[o].rson].ran<Treap[o].ran)
                rorateL(o);
        }
    }
    int query(int val,int o){
        if(!o)
            return -1;
        if(val==Treap[Treap[o].lson].sz+1)
            return Treap[o].num;
        else if(val>Treap[Treap[o].lson].sz+1)
            return query(val-Treap[Treap[o].lson].sz-1,Treap[o].rson);
        else
            return query(val,Treap[o].lson);
    }
    void dfs(int &o,int to){
        if(!o)
            return;
        insert(Treap[o].val,Treap[o].num,root[to]);
        dfs(Treap[o].lson,to);
        dfs(Treap[o].rson,to);
        throwin(o);
        o=0;
    }
    int main(){
        scanf("%d %d",&n,&m);
        for(int i=1;i<=n;i++)
            scanf("%d",&w_p[i]),fa[i]=i,insert(w_p[i],i,root[i]);
        for(int i=1;i<=m;i++){
            int a,b;
            scanf("%d %d",&a,&b);
            if(find(a)!=find(b)){
                if(Treap[find(a)].sz<Treap[find(b)].sz){
                    dfs(root[find(a)],find(b));
                    fa[find(a)]=find(b);
                }
                else{
                    dfs(root[find(b)],find(a));
                    fa[find(b)]=find(a);
                }
            }
        }
        int q;
        scanf("%d",&q);
        for(int i=1;i<=q;i++){
            char opt=getchar();
            while(opt!='B'&&opt!='Q')
                opt=getchar();
            int a,b;
            scanf("%d %d",&a,&b);
            if(opt=='B'){
                if(find(a)!=find(b)){
                    if(Treap[find(a)].sz<Treap[find(b)].sz){
                        dfs(root[find(a)],find(b));
                        fa[find(a)]=find(b);
                    }
                    else{
                        dfs(root[find(b)],find(a));
                        fa[find(b)]=find(a);
                    }
                }   
            }
            else{
                printf("%d
    ",query(b,root[find(a)]));
            }
        }
        return 0;
    }
    
  • 相关阅读:
    centos7系统中忘记了root管理员账号密码的解决方式
    【python之路48】生成器表达式、推导式
    小米集团信息化中台战略
    分时函数
    函数节流
    JS浮点计算问题
    要转型做前端开发了
    优秀的开发人员和测试人员应有的态度
    C#数组的笔记
    LINQ不包含列表
  • 原文地址:https://www.cnblogs.com/dreagonm/p/10710644.html
Copyright © 2011-2022 走看看