luoguP1456 Monkey King

左偏树模板题。注意删除操作。

#include<bits/stdc++.h>
using namespace std;
const int maxn=100010;
int ch[maxn][2],key[maxn],f[maxn],dis[maxn];
int merge(int x,int y){
    if(x==0||y==0)return x+y;
    if(key[x]<key[y])swap(x,y);
    ch[x][1]=merge(ch[x][1],y);
    f[ch[x][1]]=x;
    if(dis[ch[x][1]]>dis[ch[x][0]])swap(ch[x][1],ch[x][0]);
    dis[x]=dis[ch[x][1]]+1;
    return x;
}
int getf(int x){
    if(f[x])return getf(f[x]);
    else return x;
}
int change(int x){
    f[x]=0;
    f[ch[x][1]]=f[ch[x][0]]=0;
    int temp=merge(ch[x][1],ch[x][0]);
    ch[x][1]=ch[x][0]=0;
    key[x]/=2;
    return merge(temp,x);
}
int solve(int x,int y){
    int tx=change(x);int ty=change(y);
    return key[merge(tx,ty)];
}
int main(){
    int n,m;
    while(scanf("%d",&n)!=EOF){
        dis[0]=-1;
        for(int i=1;i<=n;++i){
            scanf("%d",&key[i]);
            f[i]=0;ch[i][0]=ch[i][1]=0;
        }
        scanf("%d",&m);
        for(int i=1;i<=m;++i){
            int x,y;
            scanf("%d%d",&x,&y);
            int fx=getf(x),fy=getf(y);
            if(fx==fy){
                printf("-1\n");
            }
            else{
                printf("%d\n",solve(fx,fy));
            }
        }
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/Dream-Runner/p/9430235.html