左偏树模板(堆合并问题)

题:https://www.luogu.com.cn/problem/P3377

#include<bits/stdc++.h>
using namespace std;
#define pb push_back
#define MP make_pair
typedef long long ll;
const int mod=1e9+7;
const int M=1e5+6;
const int inf=0x3f3f3f3f;
const ll INF=1e18;
struct node{
    int lc,rc,dis,fa,val;
}tr[M];
void init(int x){
    for(int i = 0; i <= x; i++) {
        tr[i].dis = tr[i].lc = tr[i].rc = 0;
        tr[i].fa = i;
    }
}
int Merge(int x , int y) {
    if(x == 0)return y;
    if(y == 0)return x;
    if(tr[x].val > tr[y].val || (tr[x].val == tr[y].val && x > y))
        swap(x , y);
    tr[x].rc = Merge(tr[x].rc , y);
    tr[tr[x].rc].fa = x;
    if(tr[tr[x].rc].dis > tr[tr[x].lc].dis)
        swap(tr[x].rc, tr[x].lc);

    tr[x].dis = (tr[x].rc == 0 ? 0 : tr[tr[x].rc].dis+1);
    return x;
}
int Find(int x){
    return tr[x].fa==x?x:tr[x].fa=Find(tr[x].fa);
}
void del(int x){
    int l = tr[x].lc , r = tr[x].rc;
    tr[x].dis = tr[x].lc = tr[x].rc = tr[x].fa = 0;
    tr[x].val = -inf;
    tr[l].fa = l, tr[r].fa = r;
    tr[x].fa=Merge(l , r);
}
int main(){
    int n,m;
    scanf("%d%d",&n,&m);
    init(n);
    for(int i=1;i<=n;i++)
        scanf("%d",&tr[i].val);
    while(m--){
        int op,x,y;
        scanf("%d",&op);
        if(op==1){
            scanf("%d%d",&x,&y);
            int xx=Find(x), yy=Find(y);
            if(tr[x].val==-inf||tr[y].val==-inf||xx==yy)
                continue;

            tr[x].fa=tr[y].fa=Merge(xx,yy);
        }
        else{
            scanf("%d",&x);
            if(tr[x].val==-inf){
                puts("-1");
                continue;
            }
            x=Find(x);
            printf("%d
",tr[x].val);
            del(x);
        }
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/starve/p/13620077.html