求求了解决一下孩子的疑惑
查看原帖
求求了解决一下孩子的疑惑
260360
阿噫齐贝林楼主2022/9/13 17:48

为啥fhq treap建树的规模会影响结果

#include<bits/stdc++.h>
#define int long long
using namespace std;
inline int read()
{
	int x=0,f=1;
	char c=getchar();
	while(c<'0'||c>'9'){if(c=='-') f=-1;c=getchar();}
	while(c>='0'&&c<='9'){x=(x<<3)+(x<<1)+c-48;c=getchar();}
	return x*f;
}
const int N=1000005;
int rt,num;
int n,m;
int last=0,ans=0;
struct treap{
	int val,rand,ls,rs,size;
}tr[N];
inline int New(int val)
{
	tr[++num].val=val;
	tr[num].rand=rand();
	tr[num].ls=0,tr[num].rs=0;
	tr[num].size=1;
	return num;
}
inline void Update(int p)
{
	tr[p].size =tr[tr[p].ls].size +tr[tr[p].rs].size +1;
}
inline void Split(int p,int val,int &x,int &y)
{
	if(!p){x=0,y=0;return;}
	if(tr[p].val<=val){x=p;Split(tr[p].rs,val,tr[p].rs,y);}
	else{y=p;Split(tr[p].ls,val,x,tr[p].ls);}
	Update(p);
}
inline int Merge(int x,int y)
{
	if(!x||!y) return x+y;
	if(tr[x].rand<tr[y].rand)
	{
		tr[x].rs=Merge(tr[x].rs,y);
		Update(x);
		return x;
	}
	else
	{
		tr[y].ls=Merge(x,tr[y].ls);
		Update(y);
		return y;
	}
}
inline void insert(int val)
{
	int x,y;
	Split(rt,val-1,x,y);
	rt=Merge(Merge(x,New(val)),y);
} 
inline void Delete(int val)
{
	int x,y,z;
	Split(rt,val,x,z);
	Split(x,val-1,x,y);
	rt=Merge(Merge(x,Merge(tr[y].ls,tr[y].rs)),z);
} 
inline int rnk(int val)
{
	int x,y,ass;
	Split(rt,val-1,x,y);
	ass=tr[x].size+1;
	rt=Merge(x,y);
	return ass;
}
inline int Find(int p,int Kth)
{
	if(Kth==tr[tr[p].ls].size+1) return p;
	if(Kth<=tr[tr[p].ls].size) return Find(tr[p].ls,Kth);
	return Find(tr[p].rs,Kth-tr[tr[p].ls].size-1);
}
inline int pre(int val)
{
	int x,y,ass;
	Split(rt,val-1,x,y);
	ass=tr[Find(x,tr[x].size)].val;
	rt=Merge(x,y);
	return ass;
}
inline int nxt(int val)
{
	int x,y,ass;
	Split(rt,val,x,y);
	ass=tr[Find(y,1)].val;
	rt=Merge(x,y);
	return ass;
}
signed main()
{
	srand(time(0));
	n=read(),m=read();
	int val,op;
	for(int i=1;i<=n;i++)
	{
		val=read();
		insert(val);
	}
	for(int i=1;i<= m;i++)
	{
		op=read(),val=read();
		val^=last;
		if(op==1)insert(val);
		if(op==2)Delete(val);
		if(op==3)
		{
			last=rnk(val);
			ans^=last;
		}
		if(op==4)
		{
			last=tr[Find(rt,val)].val;
			ans^=last;
		}
		if(op==5)
		{
			last=pre(val);
			ans^=last;
		}
		if(op==6)
		{
			last=nxt(val);
			ans^=last;
		}
	}
	printf("%d",ans);
}

tr[N](N=1000005)是92分

tr[2*N]能AC

题解大佬写的是tr[2*N]但我不知道为啥,或者有大佬能解释一下建树的范围有啥要注意的吗

2022/9/13 17:48
加载中...