左偏树维护最大值,并查集维护集合关系

#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;
}
View Code