左偏树模板题。注意删除操作。
#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; }