关于 FHQ treap
  • 板块学术版
  • 楼主critnos
  • 当前回复18
  • 已保存回复18
  • 发布时间2020/7/28 14:04
  • 上次更新2023/11/6 21:59:13
查看原帖
关于 FHQ treap
203623
critnos楼主2020/7/28 14:04

这是我封装的模板:

struct FHQ_treap
{
	struct node
	{
		int v,r,size;
		int s[2];
	}t[10000005];
	#define ls t[w].s[0]
	#define rs t[w].s[1]
	int cnt,root;
	int newnode(int v)
	{
		t[++cnt].v=v,t[cnt].r=rand(),t[cnt].size=1;
		return cnt;
	}
	void pushup(int w)
	{
		t[w].size=t[ls].size+t[rs].size+1;
	}
	void split(int w,int k,int &x,int &y)
	{
		if(!w) 
		{
			x=y=0;
			return;	
		}
		if(t[w].v<=k)
		{
			x=w;
			split(rs,k,rs,y);
		}
		else
		{
			y=w;
			split(ls,k,x,ls);
		}
		pushup(w);
	}
	int merge(int x,int y)
	{
		if(!x||!y) return x+y;
		if(t[x].r<t[y].r)
		{
			t[x].s[1]=merge(t[x].s[1],y);
			pushup(x);
			return x;
		}
		else
		{
			t[y].s[0]=merge(x,t[y].s[0]);
			pushup(y);
			return y;
		}
	}
	void insert(int v)
	{
		int x,y;
		split(root,v,x,y);
		root=merge(merge(x,newnode(v)),y);
	}
	void erase(int v)
	{
		int x,y,z;
		split(root,v,x,z);
		split(x,v-1,x,y);
		y=merge(t[y].s[0],t[y].s[1]);
		root=merge(merge(x,y),z);
	}
	int rank(int v)
	{
		int x,y;
		split(root,v-1,x,y);
		int ret=t[x].size+1;
		root=merge(x,y);
		return ret;
	}
	int ktw(int w,int k)
	{
		for(;;)
		{
			if(k<=t[ls].size)
				w=ls;
			else if(k==t[ls].size+1) return w;
			else k-=t[ls].size+1,w=rs;
		}
	}
	int kth(int v)
	{
		return t[ktw(root,v)].v;
	}
	int pre(int v)
	{
		int x,y;
		split(root,v-1,x,y);
		int ret=t[ktw(x,t[x].size)].v;
		root=merge(x,y);
		return ret;
	}
	int nxt(int v)
	{
		int x,y;
		split(root,v,x,y);
		int ret=t[ktw(y,1)].v;
		root=merge(x,y);
		return ret;
	}
}a;

然鹅我做了两次测速:

  1. 按顺序插入 [0,107)[0,10^7)

  2. 插入随机数据共 10710^7

测速发现:

  1. 1s+

  2. 33s+

可以看到常数的差距是巨大的。请问这是 FHQ 的特性还是所有平衡树的特性?请问为什么会这样?

2020/7/28 14:04
加载中...