非旋treap提示
查看原帖
非旋treap提示
109625
HKHbest楼主2020/12/27 19:34
#include<bits/stdc++.h>
using namespace std;
const int N=110000;
int n,root,tot;
struct FHQ_treap
{
	int key,val,siz,lson,rson;
}tree[N];
void add(int x)
{
	tree[++tot].val=x;
	tree[tot].key=rand();
	tree[tot].rson=tree[tot].lson=0;
	tree[tot].siz=1;
	return;
}
void update(int u)
{
	tree[u].siz=tree[tree[u].lson].siz+tree[tree[u].rson].siz+1;
	return;
}
void divide(int u,int x,int &l,int &r)
{
	if(u==0)
	{
		l=r=0;
		return;
	}
	int lson=tree[u].lson,rson=tree[u].rson;

	if(tree[u].val<=x)
		l=u,divide(rson,x,tree[u].rson,r);//注意这里用单个变量lson和rson代替是错误的,l与r与divide直接相关,接下来的递归中要实际改变d[u]的llson,rson值 
	else
		r=u,divide(lson,x,l,tree[u].lson);
	update(u);
}
int merge(int l,int r)
{
	if(l==0)
		return r;
	if(r==0)
		return l;
	if(tree[l].key<tree[r].key)
	{
		tree[l].rson=merge(tree[l].rson,r);
		update(l);
		return l;
	}
	else
	{
		tree[r].lson=merge(l,tree[r].lson);
		update(r);
		return r;
	}
}
int kth(int u,int k)
{
	int lson=tree[u].lson,rson=tree[u].rson;
	if(k<=tree[lson].siz)
		return kth(lson,k);
	else
	{
		if(tree[lson].siz+1==k)
		{
			return u;
		}
		else
		{
			return kth(rson,k-1-tree[lson].siz);
		}
	}
}
int main()
{
	srand(time(NULL));
	scanf("%d",&n);
	int l,r,p;
	for(int i=1,opt,x;i<=n;i++)
	{
		scanf("%d%d",&opt,&x);
		switch(opt)
		{
			case 1:
			{
				divide(root,x,l,r);
				add(x);
				root=merge(merge(l,tot),r);
				break;	
			}
			case 2:
			{
				divide(root,x,l,p); 
				divide(l,x-1,l,r);//只删除一个
				r=merge(tree[r].lson,tree[r].rson);
				root=merge(merge(l,r),p);
				break;
			}
			case 3:
			{
				divide(root,x-1,l,r);
				printf("%d\n",tree[l].siz+1);
				root=merge(l,r);
				break;
			}
			case 4:
			{
				printf("%d\n",tree[kth(root,x)].val);
				break;
			}
			case 5:
			{
				divide(root,x-1,l,r);
				printf("%d\n",tree[kth(l,tree[l].siz)].val);
				root=merge(l,r);
				break;
			}
			case 6:
			{
				divide(root,x,l,r);
				printf("%d\n",tree[kth(r,1)].val);
				root=merge(l,r);
				break;
			}
			default:
			{
				break;	
			}
		}
//		printf("%d.%d\n",i,root);//DEBUG
	}
	return 0;
}
/*
插入 xx 数
删除 xx 数(若有多个相同的数,因只删除一个)
查询 xx 数的排名(排名定义为比当前数小的数的个数 +1+1 )
查询排名为 xx 的数
求 xx 的前驱(前驱定义为小于 xx,且最大的数)
求 xx 的后继(后继定义为大于 xx,且最小的数)
*/

在分割查找树的函数中,传参数必须传实际的参数,不可以用及时定义的简化码量的变量,否则在随后的递归中会修改不正常。

也就我能犯这种错误吧(

2020/12/27 19:34
加载中...