luogu 3377【模板】左偏树(可并堆)
一切都从模板开始,我扔:https://www.luogu.org/problemnew/show/P3377
模板题嘛……就没啥好讲的了,如果不会左偏树请看这篇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