左偏树学习记录

可并堆之左偏树

(适用统计问题、最值问题、模拟问题和贪心问题)
一句话:符合堆、二叉树性质,且可实现快速合并
外节点:左儿子或右儿子为空的节点
(默认小根堆)
dist:
一个外结点的dist为1
空节点的dist为0
非外结点的dist为到达其子树的[最近的外结点]的距离+1

左偏树[左偏]:
二叉树的每个节点都满足[左儿子dist>=右儿子dist]
所以每个节点的dist一定等于其 [右儿子dist+1]

merge操作:
合并时,选取值较小的根节点cur作为合并后的根节点
cur的左儿子作为合并后堆的左儿子
cur的右儿子与另一个堆合并,作为新的右儿子
合并后如果[左儿子dist]<[右儿子dist],交换两个儿子

My_code:
//左偏树模板  luogu P3377 【模板】左偏树(可并堆)
#include <bits/stdc++.h>
using namespace std;

const int N=2e6+10;

int read() {

	int x=0,f=1;
	char ch=getchar();
	while(ch<48||ch>57) {
		if(ch=='-') f=-1;
		ch=getchar();
	}
	while(ch>=48&&ch<=57) {
		x=(x<<3)+(x<<1)+(ch^48);
		ch=getchar();
	}
	return x*f;

}

struct leftTree{
	
	int l,r;
	int val,dist;
        int rt;//father 用于记录所属堆顶,并查集查找
	
}t[N]; 

int find(int x){//并查集确定堆顶(堆顶代表这个堆) 
	
	if(t[x].rt==x) return x;
	return t[x].rt=find(t[x].rt);
	
}

int merge(int x,int y){//合并,并返回合并后的根节点编号 
	
	if(!x||!y) return x|y;
	
	if(t[x].val>t[y].val) swap(x,y);
	if(t[x].val==t[y].val&&x>y) swap(x,y);// 题目要求:若有多个最小数,优先删除先输入的
	t[x].r=merge(t[x].r,y);//合并右儿子与另一个堆 
	
	if(t[t[x].r].dist > t[t[x].l].dist) swap(t[x].l,t[x].r);//维护左儿子dist>右儿子dist性质
	t[t[x].l].rt=t[t[x].r].rt=t[x].rt=x;//update father(rt)
	t[x].dist=t[t[x].r].dist+1;//每个节点的dist一定等于其 [右儿子dist+1]
	return x;
	
}

void del(int x){//删除 
	
	t[x].val=-1;
	t[t[x].l].rt=t[x].l;//拆出左右儿子 
	t[t[x].r].rt=t[x].r;
	t[x].rt=merge(t[x].l,t[x].r);//合并成新堆 
	
}

int n,m;

int main(){
	
	n=read();
	m=read();
	
	t[0].dist=-1;
	for(int i=1;i<=n;i++){
		
		t[i].val=read();
		t[i].rt=i;//初始father为自己 
		
	}
	
	while(m--){
		
		int op=read(),x=read();
		if(op==1){
			
			int y=read();
			if(t[x].val==-1||t[y].val==-1) continue;//已删除 
			x=find(x),y=find(y);
			if(x!=y) t[x].rt=t[y].rt=merge(x,y);
			
		}
		else {
			
			if(t[x].val==-1) printf("-1\n");
			else {
				
				x=find(x);
				printf("%d\n",t[x].val);
				del(x);
				
			}
			
		}
		
	}
	return 0;
}  
posted @   Diamondan  阅读(21)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?
点击右上角即可分享
微信分享提示