ZOJ 2334 Monkey King 可并堆左偏树

来源:互联网 发布:mac teamviewer 破解 编辑:程序博客网 时间:2024/06/05 14:18

----------

int n,m;class LeftistTree{private:    int tot,v[maxn],l[maxn],r[maxn],d[maxn];public:    int merge(int x,int y){        if (!x) return y;        if (!y) return x;        if (v[x]<v[y]) swap(x,y);        r[x]=merge(r[x],y);        if (d[l[x]]<d[r[x]]) swap(l[x],r[x]);        d[x]=d[r[x]]+1;        return x;    }    int newNode(int x){        tot++;        v[tot]=x;        l[tot]=r[tot]=d[tot]=0;        return tot;    }    int insert(int rt,int val){        return merge(rt,newNode(val));    }    int top(int rt){        return v[rt];    }    int pop(int rt){        return merge(l[rt],r[rt]);    }    void clear(){        tot=0;    }}tr;int lp[maxn];int pa[maxn];void makeset(int n){    for (int i=0;i<=n;i++) pa[i]=i;}int findset(int x){    if (x!=pa[x]) pa[x]=findset(pa[x]);    return pa[x];}void unionset(int x,int y){    x=findset(x);    y=findset(y);    if (x!=y){        pa[x]=y;        lp[y]=tr.merge(lp[x],lp[y]);    }}int main(){    while (~scanf("%d",&n)){        makeset(n);        tr.clear();        for (int i=1;i<=n;i++){            int v;            scanf("%d",&v);            lp[i]=tr.newNode(v);        }        scanf("%d",&m);        for (int i=1;i<=m;i++){            int l,r;            scanf("%d%d",&l,&r);            if (findset(l)==findset(r)) printf("-1\n");            else{                int newPower,newRoot;                newPower=tr.top(lp[findset(l)])/2;                newRoot=tr.pop(lp[findset(l)]);                lp[findset(l)]=tr.insert(newRoot,newPower);                newPower=tr.top(lp[findset(r)])/2;                newRoot=tr.pop(lp[findset(r)]);                lp[findset(r)]=tr.insert(newRoot,newPower);                unionset(l,r);                printf("%d\n",tr.top(lp[findset(l)]));            }        }    }return 0;}


----------

0 0
原创粉丝点击