//左偏树+并查集
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int maxn=100005;
struct Node{
int l,r,f;
int v,d;
}node[maxn];
int f[maxn];//集合
int root[maxn];//集合的左偏树的根是谁
int n,m;
void init(){
int i;
for(i=0;i<=n;i++){
node[i].f=i;
node[i].l=node[i].r=node[i].d=0;
}
node[0].d=-1;
for(i=0;i<=n;i++){
f[i]=i;
root[i]=i;
}
}
int find(int x){
if(f[x]==x)
return x;
return f[x]=find(f[x]);
}
int Merge(int a,int b){
if(a==0) return b;
if(b==0) return a;
if(node[a].v<node[b].v) a^=b^=a^=b;
node[a].r=Merge(node[a].r,b);
node[node[a].r].f=a;
if(node[ node[a].l ].d<node[node[a].r].d)
node[a].l^=node[a].r^=node[a].l^=node[a].r;
node[a].d=node[node[a].r].d+1;
return a;
}
int Pop(int a){
int l=node[a].l;
int r=node[a].r;
node[l].f=l;
node[r].f=r;
node[a].l=node[a].r=node[a].d=0;
return Merge(l,r);
}
int Gao(int a,int b){
int x=root[find(a)];
int y=root[find(b)];
if(x==y)return -1;
node[x].v/=2;
int t1=Merge(node[x].l,node[x].r);
node[x].l=node[x].r=node[x].f=0;
t1=Merge(x,t1);
node[y].v/=2;
int t2=Merge(node[y].l,node[y].r);
node[y].l=node[y].r=node[y].f=0;
t2=Merge(y,t2);
f[find(t2)]=f[find(t1)];
root[find(t1)]=Merge(t1,t2);
return node[root[find(t1)]].v;
}
int main(){
int i;
int a,b;
while(scanf("%d",&n)!=EOF){
init();
for(i=1;i<=n;i++){
scanf("%d",&node[i].v);
}
scanf("%d",&m);
for(i=0;i<m;i++){
scanf("%d%d",&a,&b);
if(find(a)==find(b))
puts("-1");
else{
int ans=Gao(a,b);
printf("%d\n",ans);
}
}
}
return 0;
}
Monkey King zoj 2334
最新推荐文章于 2017-04-19 16:50:00 发布