• cogs1341 永无乡


    cogs1341 永无乡


    打了一发替罪羊树。
    鬼故事:替罪羊树去掉重构(变成裸的二叉排序树)依然跑得过= =
    启发式合并。每次把小的里面所有东西往大的里面一丢,每个点最多被丢(log_2n)次(丢一次大小至少*2)
    然后这题就写完了(替罪羊树很暴力,启发式合并也很暴力)
    还要搞个并查集维护连通性,连通的就不用再合了。
    (好像不兼容O2)

    // It is made by XZZ
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    #define rep(a,b,c) for(rg int a=b;a<=c;a++)
    #define drep(a,b,c) for(rg int a=b;a>=c;a--)
    #define erep(a,b) for(rg int a=fir[b];a;a=nxt[a])
    #define il inline
    #define rg register
    #define vd void
    typedef long long ll;
    il int gi(){
        rg int x=0;rg bool flg=0;rg char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')flg=1;ch=getchar();}
        while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
        return flg?-x:x;
    }
    const double alpha=0.723333;
    const int maxn=100010;
    int fa[maxn];
    int siz[maxn],v[maxn],ch[maxn][2];
    il int hd(int a){return a==fa[a]?a:fa[a]=hd(fa[a]);}
    il int*_insert(int&x,const int&y){
        if(!x){x=y,siz[x]=1,ch[x][0]=ch[x][1]=0;return NULL;}
        ++siz[x];
        int*p=_insert(ch[x][v[y]>v[x]],y);
        if(alpha*siz[x]<max(siz[ch[x][0]],siz[ch[x][1]]))p=&x;
        return p;
    }
    int tot,res[maxn];
    il vd _dfs(const int&x){if(x)_dfs(ch[x][0]),res[++tot]=x,_dfs(ch[x][1]);}
    il vd redo(const int&x,const int &k){if(x)_dfs(ch[x][0]),_dfs(ch[x][1]),fa[x]=k;}
    il int divide(int l,int r){
        if(l>r)return 0;
        int mid=(l+r)>>1;
        ch[res[mid]][0]=divide(l,mid-1);
        ch[res[mid]][1]=divide(mid+1,r);
        siz[res[mid]]=r-l+1;
        return res[mid];
    }
    il vd insert(int&x,const int&y){
        int*p=_insert(x,y);
        if(p){//这里if(p)改成if(0)就是裸的BST
            int&k=*p,s;
            tot=0,_dfs(k);
            if(k==x)s=divide(1,tot),fa[x]=x=fa[s]=s;
            else k=divide(1,tot);
        }
    }
    il vd dfs(const int&x,int&y){
        if(!x)return;
        dfs(ch[x][0],y),dfs(ch[x][1],y);
        insert(y,x);
    }
    il vd Union(int a,int b){
        int A=hd(a),B=hd(b);
        if(A==B)return;
        if(siz[A]>siz[B])dfs(B,A),fa[B]=A;
        else dfs(A,B),fa[A]=B;
    }
    int main(){
        int n=gi(),m=gi();
        rep(i,1,n)v[i]=gi(),siz[i]=1,fa[i]=i;
        while(m--)Union(gi(),gi());
        int q=gi();char opt[2];
        while(q--){
            scanf("%s",opt);
            if(opt[0]=='Q'){
                static int x,y;
                x=hd(gi()),y=gi();
                if(siz[x]<y){puts("-1");continue;}
                while(1){
                    if(siz[ch[x][0]]+1==y){printf("%d
    ",x);break;}
                    if(y<=siz[ch[x][0]])x=ch[x][0];
                    else y-=siz[ch[x][0]]+1,x=ch[x][1];
                }
            }else Union(gi(),gi());
        }
        return 0;
    }
    
  • 相关阅读:
    Coding.net进阶,使用Git管理代码
    经典算法问题
    浅谈三款常用软件
    Coding.net简单使用指南
    湖北宜化总结
    天顺风能经验总结
    Vue中watch的高级用法
    html 锚点三种实现方法
    【机器学习】EM算法详细推导和讲解
    【机器学习】BP神经网络实现手写数字识别
  • 原文地址:https://www.cnblogs.com/xzz_233/p/cogs1341.html
Copyright © 2020-2023  润新知