1. 程式人生 > >luogu 3377【模板】左偏樹(可並堆)

luogu 3377【模板】左偏樹(可並堆)

模板題嘛……就沒啥好講的了,如果不會左偏樹請看這篇blog

程式碼,上:

#include<bits/stdc++.h>
#define N 200005
using namespace std;
int fa[N], ch[N][2], key[N], dis[N], tot;
void newnode(int x){
    tot ++;
    key[tot] = x;
}
int merge(int x, int y){//模板啊……
    if(!x || !y) return x + y;
    if(key[x] > key[y] || key[x] == key[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;
}
int find(int x){
    for(;fa[x];) x = fa[x];
    return x;
}
int n, m;
int main(){
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= n; i ++){ 
        int x;
        scanf("%d", &x);
        newnode(x);
    }
    for(;m --;){
        int c, x, y;
        scanf("%d", &c);
        if(c == 1){
            scanf("%d%d", &x, &y);
            if(x == y || key[x] == -1 || key[y] == -1) continue; //要注意一下細節
            x = find(x), y = find(y);
            merge(x, y);
        }else{
            scanf("%d", &x);
            x = find(x);
            printf("%d\n", key[x]);
            if(key[x] == -1) continue;
            key[x] = -1;
            fa[x] = fa[ch[x][0]] = fa[ch[x][1]] = 0;
            merge(ch[x][0], ch[x][1]);
        }
    }
    return 0;
}

由於細節沒有1A QAQ