luogu3377 【模板】左偏树(可并堆)

ref

#include <iostream>
#include <cstdio>
using namespace std;
int n, m, a[100005], opt, uu, vv, fa[100005], ch[100005][2], dis[100005];
int myfind(int x){
    while(fa[x])    x = fa[x];
    return x;
}
int merge(int x, int y){
    if(!x || !y)    return x+y;
    if(a[x]>a[y] || (a[x]==a[y] && x>y))    swap(x, y);
    ch[x][1] = merge(ch[x][1], y);
    fa[ch[x][1]] = x;
    if(dis[ch[x][0]]<dis[ch[x][1]]) swap(ch[x][0], ch[x][1]);
    dis[x] = dis[ch[x][1]] + 1;
    return x;
}
void pop(int x){
    a[x] = -1;
    fa[ch[x][0]] = fa[ch[x][1]] = 0;
    merge(ch[x][0], ch[x][1]);
}
int main(){
    cin>>n>>m;
    for(int i=1; i<=n; i++)
        scanf("%d", &a[i]);
    while(m--){
        scanf("%d", &opt);
        if(opt==1){
            scanf("%d %d", &uu, &vv);
            if(a[uu]<0 || a[vv]<0)  continue;
            uu = myfind(uu);
            vv = myfind(vv);
            if(uu!=vv)  merge(uu, vv);
        }
        else{
            scanf("%d", &uu);
            if(a[uu]<0){
                printf("-1\n");
                continue;
            }
            uu = myfind(uu);
            printf("%d\n", a[uu]);
            pop(uu);
        }
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/poorpool/p/9010590.html