左偏树维护最大值,并查集维护集合关系
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; int n,m; struct Monkey { int x,dis,t; Monkey *l,*r,*fa; void clear() { l=r=fa=NULL; } }a[100011]; Monkey *find_fa(Monkey *T) { if (T->fa==NULL) return T; else return find_fa(T->fa); } bool check_dis(Monkey *A,Monkey *B) { if (A->r==NULL) return false; if (A->l==NULL) return true; return (A->r->dis>A->l->dis); } Monkey *merge(Monkey *A,Monkey *B) { if (A==NULL) return B; if (B==NULL) return A; if (A->x<B->x) swap(A,B); A->r=merge(A->r,B); if (check_dis(A,B)) swap(A->l,A->r); if (A->r==NULL) A->dis=0; else A->dis=A->r->dis+1; if (A->l!=NULL) A->l->fa=A; if (A->r!=NULL) A->r->fa=A; return A; } Monkey *delet(Monkey *A) { if (A->l!=NULL) A->l->fa=NULL; if (A->r!=NULL) A->r->fa=NULL; Monkey *B; B=merge(A->l,A->r); A->l=A->r=NULL; A->x=A->x/2; return merge(A,B); } void init() { for (int i=1;i<=n;i++) scanf("%d",&a[i].x),a[i].clear(),a[i].t=i; scanf("%d",&m); int A,B; Monkey *pA,*pB; for (int i=1;i<=m;i++) { scanf("%d%d",&A,&B); pA=find_fa(&a[A]); pB=find_fa(&a[B]); if (pA==pB) { printf("-1\n"); continue; } pA=delet(pA);pB=delet(pB); pA=merge(pA,pB); printf("%d\n",pA->x); } } int main() { while (cin>>n) init(); return 0; }