阿噫齐贝林 @ 2022-09-13 17:48: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]但我不知道为啥,或者有大佬能解释一下建树的范围有啥要注意的吗
by 鏡音リン @ 2022-09-13 17:52:05
@阿噫齐贝林 其实N+M就行吧……
本来有1e5个点,有1e6次插入操作,所以是1100000……
by COsm0s @ 2022-09-13 18:15:48
管理楼下,且楼上正解
by 阿噫齐贝林 @ 2022-09-14 17:00:59
@鏡音リン orz懂了懂了谢谢管理员大爷