萌新求助无旋treap
查看原帖
萌新求助无旋treap
37885
冷笑叹秋萧楼主2021/11/14 21:49

样例前两个询问输出了0(找第k小和后继),第三个询问死循环(找前驱),找了好久找不出错

#include<bits/stdc++.h> 
#define R register int
#define N 100005
using namespace std;
int tree[N][2],rnd[N],val[N],size[N],cnt,rt,n;
void maintain(int now) {size[now]=size[tree[now][0]]+size[tree[now][1]]+1;}
void split(int now,int &x,int &y,int k)
{
	if (!now) {x=y=0;return;}
	if (val[now]<=k)
	{
		x=now;split(tree[now][1],tree[now][1],y,k);
	}
	else
	{
		y=now;split(tree[now][0],x,tree[now][0],k);
	}
	maintain(now);
}
int merge(int x,int y)
{
	if (!x || !y) return x+y;
	if (rnd[x]<rnd[y])
	{
		tree[x][1]=merge(tree[x][1],y);
		maintain(x);return x;
	}
	else
	{
		tree[y][0]=merge(x,tree[y][0]);
		maintain(y);return y;
	}
}
int new_node(int k)
{
	size[++cnt]=1;val[cnt]=k;rnd[cnt]=rand();return cnt;
}
void ins(int k)
{
	int x,y;
	split(rt,x,y,k);merge(merge(x,new_node(k)),y);
}
void del(int k)
{
	int x,y,z;
	split(rt,x,y,k);split(x,x,z,k-1);
	z=merge(tree[z][0],tree[z][1]);rt=merge(merge(x,z),y);
}
int rnk(int k)
{
	int x,y;
	split(rt,x,y,k-1);int res=size[x]+1;
	rt=merge(x,y);return res;
}
int kth(int now,int k)
{
	if (k<=size[tree[now][0]]) return kth(tree[now][0],k);
	k-=size[tree[now][0]]+1;
	if (!k) return now;else return kth(tree[now][1],k);
}
int pre(int k)
{
	int x,y;
	split(rt,x,y,k-1);int res=val[kth(x,size[x])];
	rt=merge(x,y);return res;
}
int nxt(int k)
{
	int x,y;
	split(rt,x,y,k);int res=val[kth(y,1)];
	rt=merge(x,y);return res;
}
int main()
{
	srand(time(0));scanf("%d",&n);
	for (R opt,x,i=1;i<=n;++i)
	{
		scanf("%d%d",&opt,&x);
		if (opt==1) ins(x);
		else if (opt==2) del(x);
		else if (opt==3) printf("%d\n",rnk(x));
		else if (opt==4) printf("%d\n",val[kth(rt,x)]);
		else if (opt==5) printf("%d\n",pre(x));
		else printf("%d\n",nxt(x)); 
	}
	return 0;
}
2021/11/14 21:49
加载中...