treap玄学出错。
查看原帖
treap玄学出错。
510815
B天选之子B楼主2022/5/10 12:18

RT,写的treap,在洛谷上交了七八次都是AC,但在本机测的时候大概两三次就会随机WA一次。 请问是我自己的代码写臭了吗?还是treap特性?

代码如下:

#include<bits/stdc++.h>
#define inf 1000000000
using namespace std;
struct T{
	int val,cnt,rnd,l,r,sz;
}t[100011];
int n,tot,ans,root;
int New(int x)
{
	t[++tot].val=x;
	t[tot].cnt=t[tot].sz=1,t[tot].rnd=rand();
	return tot;
}
void upd(int x)
{
	t[x].sz=t[t[x].l].sz+t[t[x].r].sz+t[x].cnt;
}
void bui()
{
	New(-inf);New(inf);
	root=1,t[1].r=2;
	upd(root);
}
void zig(int &x)
{
	int y=t[x].l;
	t[x].l=t[y].r,t[y].r=x,x=y;
	upd(t[x].r);upd(x);
}
void zag(int &x)
{
	int y=t[x].r;
	t[x].r=t[y].l,t[y].l=x,x=y;
	upd(t[x].l);upd(x);
}
void ins(int &x,int z)
{
	if(!x) {x=New(z);return;}
	if(t[x].val==z)
	{
		t[x].cnt++;upd(x);
		return;
	}
	if(z<t[x].val)
	{
		ins(t[x].l,z);
		if(t[x].rnd<t[t[x].l].rnd) zig(x);
	}
	else
	{
		ins(t[x].r,z);
		if(t[x].rnd>t[t[x].r].rnd) zag(x);
	}
	upd(x);
}
void del(int &x,int z)
{
	if(!x) return;
	if(z==t[x].val)
	{
		if(t[x].cnt>1)
		{
			t[x].cnt--;upd(x);
			return;
		}
		if(t[x].l||t[x].r)
		{
			t[t[x].l].rnd>t[t[x].r].rnd?zig(x),del(t[x].r,z):zag(x),del(t[x].l,z);
			upd(x);
		}
		else x=0;
		return;
	}
	z<t[x].val?del(t[x].l,z):del(t[x].r,z);
	upd(x);
}
int getrank(int x,int z)
{
	if(!x) return 0;
	if(z==t[x].val) return t[t[x].l].sz+1;
	if(z<=t[x].val) return getrank(t[x].l,z);
	return getrank(t[x].r,z)+t[t[x].l].sz+t[x].cnt;
}
int getval(int x,int z)
{
	if(!x) return inf;
	if(t[t[x].l].sz>=z) return getval(t[x].l,z);
	if(t[t[x].l].sz+t[x].cnt>=z) return t[x].val;
	return getval(t[x].r,z-t[t[x].l].sz-t[x].cnt);
}
int getlas(int z)
{
	int s=1,x=root;
	while(x)
	{
		if(z==t[x].val)
		{
			if(t[x].l)
			{
				x=t[x].l;
				while(t[x].r) x=t[x].r;
				s=x;break;
			}
			
		}
		if(t[x].val<z&&t[x].val>t[s].val) s=x;
		x=z<t[x].val?t[x].l:t[x].r; 
	}
	return t[s].val;
}
int getnxt(int z)
{
	int s=2,x=root;
	while(x)
	{
		if(z==t[x].val)
		{
			if(t[x].r)
			{
				x=t[x].r;
				while(t[x].l) x=t[x].l;
				s=x;
			}
			break;
		}
		if(t[x].val>z&&t[x].val<t[s].val) s=x;
		x=z<t[x].val?t[x].l:t[x].r; 
	}
	return t[s].val;
}
int main()
{
//	freopen("P3369.in","r",stdin);
//	freopen("P3369.out","w",stdout);
	srand(time(0));
	scanf("%d",&n);
	bui();
	int op,x;
	while(n--)
	{
		scanf("%d%d",&op,&x);
		switch(op)
		{
			case 1:{
				ins(root,x);
				break;
			}
			case 2:{
				del(root,x);
				break;
			}
			case 3:{
				ans=getrank(root,x)-1;
				printf("%d\n",ans);
				break;
			}
			case 4:{
				ans=getval(root,x+1);
				printf("%d\n",ans);
				break;
			}
			case 5:{
				ans=getlas(x);
				printf("%d\n",ans);
				break;
			}
			case 6:{
				ans=getnxt(x);
				printf("%d\n",ans);
				break;
			}
		}
	}
	return 0;
}
2022/5/10 12:18
加载中...