C16【模板】左偏树(可并堆)
视频链接:236 左偏树 可并堆【模板】_哔哩哔哩_bilibili
#include <iostream> #include <cstring> #include <algorithm> using namespace std; const int N=1e5+10; int v[N],lc[N],rc[N],dis[N]; //左偏树 int fa[N]; //并查集 int find(int x){ //并查集找根 return x==fa[x] ? x : fa[x]=find(fa[x]); } int merge(int x,int y){ if(!x||!y) return x+y; //若一个堆为空则返回另一个堆 if(v[x]==v[y] ? x>y : v[x]>v[y]) swap(x,y); //取小值做根 rc[x]=merge(rc[x],y); //递归合并右儿子与另一个堆 if(dis[lc[x]]<dis[rc[x]]) swap(lc[x],rc[x]); //维护左偏性 dis[x]=dis[rc[x]]+1; //更新dis return x; //返回合并后的根 } int main(){ int n,m; scanf("%d%d",&n,&m); for(int i=1; i<=n; i++) scanf("%d",&v[i]); for(int i=1; i<=n; i++) fa[i]=i; dis[0]=-1; //空节点的dis初始化 for(int op,x,y; m; m--){ scanf("%d",&op); if(op==1){ //合并堆 scanf("%d%d",&x,&y); if(v[x]==-1 || v[y]==-1) continue; x=find(x), y=find(y); if(x!=y) fa[x]=fa[y]=merge(x,y); } else{ //删除堆顶 scanf("%d",&x); if(v[x]==-1){printf("-1\n"); continue;} x=find(x); printf("%d\n",v[x]); v[x]=-1; //删除标记 fa[lc[x]]=fa[rc[x]]=fa[x]=merge(lc[x],rc[x]); } } }
练习:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!