左偏树
左偏树
左偏树是一种可并堆,学来做
左偏树满足堆的性质,以及一个新的左偏性质。
先放定义:定义外部节点为没有左儿子或右儿子的节点。定义一个节点的距离(dis)为它到子树内最近的外部节点的距离,特别的,空节点的
根据这个定义,可以推出一棵以
左偏性质即为对于每个点
合并
可并堆最重要的就是合并了!
对于两个小根堆的根
其他操作
加入:直接当作合并来做
删除:若删除的点为根,则直接合并左右子树就好。若删除的点不为根,则需要额外维护每个点的父节点,并且在合并完儿子后,需要向上维护左偏性质。
Code
#include<bits/stdc++.h> using namespace std; const int N=2e6+5; struct Date{ int ls,rs,dis,co,fa;long long x; };Date d[N*2]; struct QUE{ int op,x,y;long long z; };QUE que[N]; int ss,rt[N],tot,a[N];long long ans[N]; int heap_newnode(long long k) { tot++;d[tot].x=k;d[tot].co=tot;rt[tot]=tot;d[tot].dis=0;return tot; } int heap_find(int x) { if(d[x].co==x) return x; return d[x].co=heap_find(d[x].co); } int heap_merge(int x,int y) { if(x==0||y==0) return x+y; if(d[x].x>d[y].x) swap(x,y); d[x].rs=heap_merge(d[x].rs,y); d[d[x].rs].fa=x; if(d[d[x].ls].dis<d[d[x].rs].dis) swap(d[x].ls,d[x].rs); d[x].dis=d[d[x].rs].dis+1; return x; } void heap_update(int x) { if(x==0) return; if(d[d[x].ls].dis<d[d[x].rs].dis) swap(d[x].ls,d[x].rs); heap_update(d[x].fa); } void heap_del(int x,int y) { x=heap_find(x); if(rt[x]==y) rt[x]=heap_merge(d[y].ls,d[y].rs); else { x=heap_merge(d[y].ls,d[y].rs); if(d[d[y].fa].ls==y) d[d[y].fa].ls=x; else d[d[y].fa].rs=x; d[x].fa=d[y].fa; heap_update(x); } } long long heap_min(int x) { x=heap_find(x); return d[rt[x]].x; } void heap_Merge(int x,int y) { x=heap_find(x);y=heap_find(y); d[y].co=x; rt[x]=heap_merge(rt[x],rt[y]); } int main() { int n,m,i,x,y; scanf("%d%d",&n,&m); d[0].dis=-1; for(i=1;i<=n;i++) { scanf("%d",&x); a[i]=heap_newnode(x); } for(i=1;i<=m;i++) { scanf("%d",&que[i].op); if(que[i].op==0) scanf("%d%d",&que[i].x,&que[i].y); if(que[i].op==1) scanf("%d",&que[i].x); if(que[i].op==2) scanf("%d%d",&que[i].x,&que[i].y); if(que[i].op==3) scanf("%d%d%lld",&que[i].x,&que[i].y,&que[i].z); } for(i=1;i<=m;i++) { x=a[que[i].x];y=a[que[i].y]; if(que[i].op==0) heap_del(x,y); if(que[i].op==1) ans[++ss]=heap_min(x); if(que[i].op==2) heap_Merge(x,y); if(que[i].op==3) { heap_del(x,y); heap_Merge(x,a[que[i].y]=heap_newnode(que[i].z)); } } for(i=1;i<=ss;i++) printf("%lld\n",ans[i]); return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话