hdu1512 Monkey King

 

http://acm.hdu.edu.cn/showproblem.php?pid=1512

 

大约是个左偏树模拟大架裸题

分离出两mokey所在堆的根节点,改变key值后插入,合并两mokey

#include<cstdio>
#include<algorithm>
inline int read() {
    int x=0;
    char c=getchar();
    while(c<'0'||c>'9')c=getchar();
    while(c<='9'&&c>='0')x=x*10+c-'0',c=getchar();
    return x;
}
const int maxn = 100007;
struct Node {
    int ls,rs,dis,key;
    Node() {}
    Node(int _key,int _l,int _r,int _d) :
        ls(_l),rs(_r),dis(_d),key(_key) {}
}tree[maxn];
int sta[maxn],n,q,father[maxn];
int find(int x) {
    if(x!=father[x])father[x]=find(father[x]);        return father[x];
}
int merge(int x,int y) {
    if(!x||!y)return x+y;
    if(tree[x].key<tree[y].key)std::swap(x,y);
    tree[x].rs=merge(y,tree[x].rs);
    if(tree[tree[x].ls].dis<tree[tree[x].rs].dis)std::swap(tree[x].ls,tree[x].rs);
    tree[x].dis=tree[tree[x].rs].dis+1;
    return x;
}
int main() {
    while(~scanf("%d",&n)) {
        for(int a,i=1;i<=n;++i) {
            a=read();father[i]=i;
            tree[i]=Node(a,0,0,0);
        }
        q=read();
        for(int a,b;q;q--) {
            a=read(),b=read();
            int fa=find(a),fb=find(b);
            if(fa==fb){puts("-1");continue;}
            a=merge(tree[fa].ls,tree[fa].rs);
            tree[fa]=Node(tree[fa].key>>1,0,0,0);
            b=merge(tree[fb].ls,tree[fb].rs);
            tree[fb]=Node(tree[fb].key>>1,0,0,0);
            a=merge(a,b);
            a=merge(a,merge(fa,fb));
            father[fa]=father[fb]=father[a]=a;
            printf("%d\n",tree[a].key);
        }
    }
    return 0;
}

 

posted @ 2017-12-23 11:34  zzzzx  阅读(213)  评论(0编辑  收藏  举报