Hdu 1512 Monkey King(左偏树+并查集)

来源:互联网 发布:机锋淘宝认证店靠谱吗? 编辑:程序博客网 时间:2024/06/05 16:39

题目地址:http://acm.split.hdu.edu.cn/showproblem.php?pid=1512

思路:

使用左偏树快速合并两堆。

#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;const int maxn=100000+50;struct Node{    int val,lson,rson,d;};int n;int fa[maxn];Node tree[maxn];int Find(int x){    return fa[x]==x?x:fa[x]=Find(fa[x]);}inline void init(int id,int x){    fa[id]=id;    tree[id].val=x;    tree[id].lson=0;    tree[id].rson=0;    tree[id].d=0;}int Merge(int x,int y){    if(!x) return y;    if(!y) return x;    if(tree[x].val<tree[y].val) swap(x,y);    tree[x].rson=Merge(tree[x].rson,y);    fa[tree[x].rson]=x;    if(tree[tree[x].lson].d<tree[tree[x].rson].d) swap(tree[x].lson,tree[x].rson);    if(!tree[x].rson) tree[x].d=0;    else tree[x].d=tree[tree[x].rson].d+1;    return x;}int Pop(int x){    int l=tree[x].lson;    int r=tree[x].rson;    fa[l]=l,fa[r]=r;    tree[x].lson=tree[x].rson=tree[x].d=0;    return Merge(l,r);}int main(){    while(scanf("%d",&n)!=EOF)    {        for(int i=1; i<=n; i++)        {            int x;            scanf("%d",&x);            init(i,x);        }        int q;        scanf("%d",&q);        for(int i=1;i<=q;i++)        {            int x,y;            scanf("%d%d",&x,&y);            int fax=Find(x),fay=Find(y);            if(fax!=fay)            {                int r1=Pop(fax),r2=Pop(fay);                tree[fax].val/=2,tree[fay].val/=2;                r1=Merge(r1,fax);                r2=Merge(r2,fay);                r1=Merge(r1,r2);                printf("%d\n",tree[r1].val);            }            else            {                printf("-1\n");            }        }    }    return 0;}




原创粉丝点击