题目地址:点击打开链接
【分析】
...左偏树裸题
【代码】
/*************************
ID:Ciocio
LANG:C++
DATE:2014-1-27
TASK:monkey king
*************************/
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
#define MAXN 100000
int key[MAXN+10],ls[MAXN+10],rs[MAXN+10];
int fa[MAXN+10],dis[MAXN+10];
int N,M,tot=1;
void _read(int &x){
char t=getchar();
while(t<'0'||'9'<t) t=getchar();
for(x=0;'0'<=t&&t<='9';x=x*10+t-'0',t=getchar());
}
void _init(){
_read(N);
dis[0]=-1;
for(int i=1;i<=N;i++){
_read(key[i]);
ls[i]=rs[i]=dis[i]=0;
fa[i]=i;
}
}
int _getfa(int x){
return x==fa[x]?x:fa[x]=_getfa(fa[x]);
}
int _merge(int x,int y){
if(x==0) return y;
if(y==0) return x;
if(key[x]<key[y])
swap(x,y);
rs[x]=_merge(rs[x],y);
fa[rs[x]]=x;
if(dis[rs[x]]>dis[ls[x]])
swap(rs[x],ls[x]);
if(rs[x]==0)
dis[x]=0;
else
dis[x]=dis[rs[x]]+1;
return x;
}
int _del(int x){
int a;
fa[ls[x]]=ls[x];
fa[rs[x]]=rs[x];
a=_merge(ls[x],rs[x]);
ls[x]=rs[x]=dis[x]=0;
return _merge(a,x);
}
void _solve(){
int x,y,a,b,ans;
_read(M);
for(int i=1;i<=M;i++){
_read(x);_read(y);
x=_getfa(x);
y=_getfa(y);
if(x==y)
printf("-1\n");
else{
key[x]>>=1;a=_del(x);
key[y]>>=1;b=_del(y);
ans=_merge(a,b);
printf("%d\n",key[ans]);
}
}
}
int main(){
_init();
_solve();
return 0;
}