可并堆

变量

  • Node a[x]\texttt{Node a[x]}:第 xx 个节点的信息。
  • int a[x].id\texttt{int a[x].id}:节点 xx 的编号。
  • int a[x].val\texttt{int a[x].val}:节点 xx 的值。
  • int a[x].l\texttt{int a[x].l}:节点 xx 的左儿子。
  • int a[x].r\texttt{int a[x].r}:节点 xx 的右儿子。
  • int a[x].dist\texttt{int a[x].dist}:节点 xx 的深度。
  • int a[x].em\texttt{int a[x].em}:标记节点 xx 是否为空。

函数

  • Node::bool operator < (Node x)\texttt{Node::bool operator < (Node x)}:重载小于号,为小根堆,值相同以编号小的为优先级高。
  • Mergeable_Heap()\texttt{Mergeable\_Heap()}:初始化。
  • void insert(int x,int val)\texttt{void insert(int x,int val)}:新建一个值为 valval,编号为 xx 的堆。
  • int merge_heap(int x,int y)\texttt{int merge\_heap(int x,int y)}:合并堆/节点 xxyy,返回合并后的节点。
  • void merge(int x,int y)\texttt{void merge(int x,int y)}:合并节点 xx 所在的堆和 yy 所在的堆。
  • bool remove(int x)\texttt{bool remove(int x)}:删除节点 xx 所在的堆的堆顶元素,如果删除成功则返回 11,否则返回 00
  • int top(int x)\texttt{int top(int x)}:返回 xx 所在的堆的堆顶元素的值。

代码

struct Mergeable_Heap{
	struct Node{
		int id,val,l,r,dist,em;
		bool operator < (Node x) const{
			return (val==x.val?id<x.id:val<x.val);
		}
	}a[N];
	Mergeable_Heap(){
		a[0].dist=0;
	}
	void insert(int x,int val){
		a[x].id=x;
		a[x].val=val;
		mfs.fa[x]=x;
		a[x].em=0;
	}
	int merge_heap(int x,int y){
		if(!x||!y)
			return x+y;
		if(a[y]<a[x])
			swap(x,y);
		a[x].r=merge_heap(a[x].r,y);
		if(a[a[x].l].dist<a[a[x].r].dist)
			swap(a[x].l,a[x].r);
		a[x].dist=a[a[x].r].dist+1;
		return x;
	}
	void merge(int x,int y){
		if(a[x].em||a[y].em)
			return;
		x=mfs.get(x);
		y=mfs.get(y);
		if(x!=y)
			mfs.fa[x]=mfs.fa[y]=merge_heap(x,y);
	}
	bool remove(int x){
		if(a[x].em)
			return 0;
		x=mfs.get(x);
		a[x].em=1;
		mfs.fa[a[x].l]=mfs.fa[a[x].r]=mfs.fa[x]=merge_heap(a[x].l,a[x].r);
		a[x].l=a[x].r=a[x].dist=0;
		return 1;
	}
	int top(int x){
		if(a[x].em)
			return -1;
		x=mfs.get(x);
		return a[x].val;
	}
}h;
posted @ 2022-09-29 13:21  luckydrawbox  阅读(6)  评论(0)    收藏  举报  来源