HDU1512 左偏树(可并堆)

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;

const int dmax=100005;
struct node{
    int v,dis;
    int l,r;
    node(){
        l=0,r=0,v=dis=0;
    }
};
struct node t[dmax]; 
struct node h,p,q;
int f[dmax],n,m;

int fa(int x){
    while (x!=f[x])
        x=f[x];
    return x;
}
int merge(int x,int y){
    if (x==0) return y;
    if (y==0) return x;
    if (t[x].v<t[y].v)
        swap(x,y);
    t[x].r=merge(t[x].r,y);
    int l=t[x].l,r=t[x].r;
    f[r]=x;
    if (t[l].dis<t[r].dis)
        swap(t[x].l,t[x].r);
    if (!t[x].r)
        t[x].dis=0;
    else t[x].dis=t[t[x].r].dis+1;
    return x;
}
int del(int x){
    int l=t[x].l,r=t[x].r;
    f[l]=l;
    f[r]=r;
    t[x].l=t[x].r=t[x].dis=0;
    return merge(l,r);
}
void solve(int x,int y){
    t[x].v/=2,t[y].v/=2;
    int left,right;
    left=del(x),right=del(y);
    left=merge(left,x),right=merge(right,y);
    left=merge(left,right);
    printf("%d\n",t[left].v);
}

int main(){
while (scanf("%d",&n)!=EOF){
    for (int i=1;i<=n;i++)
        t[i].l=t[i].r=t[i].dis=0;
    for (int i=1;i<=n;i++){
        scanf("%d",&t[i].v);
        f[i]=i;
    }
    scanf("%d",&m);
    for (int i=1;i<=m;i++){
        int x,y;
        scanf("%d%d",&x,&y);
        int fx=fa(x),fy=fa(y);
        if (fx==fy)
            puts("-1");
        else
            solve(fx,fy);
    }
}
    return 0;
}


 
 
 

你可能感兴趣的:(HDU1512 左偏树(可并堆))