第一道左偏树。
贴个模板纪念一下(因为没看到多组数据WA了一发。。 )
Code:
#include<cstdio>
#include<cctype>
#include<algorithm>
#define maxn 100005
using namespace std;
inline void read(int &a){
char c;while(!isdigit(c=getchar()));
for(a=c-'0';isdigit(c=getchar());a=a*10+c-'0');
}
struct node{
int l,r,v,d;
}t[maxn];
int fa[maxn],n,m;
int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);}
int merge(int x,int y){
if(!x||!y) return x+y;
if(t[x].v<t[y].v) swap(x,y);
y=merge(t[x].r,y);
t[x].r=y,fa[y]=x;
if(t[t[x].l].d<t[t[x].r].d) swap(t[x].l,t[x].r);
t[x].d=t[t[x].r].d+1;
return x;
}
int solve(int x){
int y=merge(t[x].l,t[x].r);
fa[y]=y,t[x].l=t[x].r=t[x].d=0,t[x].v/=2;
return merge(x,y);
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("H.in","r",stdin);
#endif
t[0].d=-1;
while(~scanf("%d",&n)){
for(int i=1;i<=n;i++) read(t[i].v),t[i].l=t[i].r=t[i].d=0,fa[i]=i;
read(m);int x,y;
while(m--){
read(x),read(y),x=find(x),y=find(y);
if(x==y) puts("-1");
else{
x=solve(x),y=solve(y);
printf("%d\n",t[merge(x,y)].v);
}
}
}
}