配对堆

一种可并堆。
插入、合并复杂度为O(1),删除等操作的复杂度为均摊O(logn)

优点:代码短,常数小。

配对堆的结构

用左儿子右兄弟的方式存树。

对每个结点,储存其右兄弟和最左端的儿子。

操作

merge(x,y):合并以x,y为根的两个配对堆。若x,y中有空树则返回非空树,否则将节点大的一棵树插入到小的树中(假设是小根堆)。

insert(x):插入一个点。直接merge(x,root)。

pop(x):删除堆顶元素。将根的所有子树从左到右两两合并,再从右到左依次合并。

代码实现

void ins(int x,int y)
{
	a[y].r=a[x].a;
	a[x].s=y;
}

void kill(int x)
{
	a[root].s=a[x].r;
	a[x].r=0;
}

int merge(int x)
{
	if(!x||!y)
		return x+y;
	if(a[x].x>a[y].x)
		swap(x,y);
	ins(x,y);
	return x;
}

void push(int x)
{
	a[x].s=a[x].r=0;
	root=merge(root,x);
}

int del()
{
	if(!a[root].s)
		return 0;
	int x=a[root].s,y=a[x].r;
	kill(x);
	if(y)
		kill(y);
	return merge(merge(x,y),del());
}

int pop()
{
	int r=a[root].x;
	root=del();
	return r;
}

int top()
{
	return a[root].x;
}

题目推荐

1.洛谷P2713 罗马游戏

2.洛谷P1552 派遣(APIO2012)

posted on 2020-07-18 21:04  Allen_lml  阅读(427)  评论(0编辑  收藏  举报