RT,本人最开始的一份代码:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll n;
ll cnt;
ll rt[200005];
struct tree
{
int son[2],size,lz; int val;ll sum;
int rk;
#define ls(x) tr[x].son[0]
#define rs(x) tr[x].son[1]
}tr[50000005];
int new_node(ll v)
{
++cnt;tr[cnt].sum=v;tr[cnt].val=v;tr[cnt].rk=rand();tr[cnt].size=1;return cnt;
}
int copy_node(int id)
{
++cnt;tr[cnt]=tr[id];
tr[cnt].rk=rand();
return cnt;
}
void pushdown(int id)
{
if(!tr[id].lz)return;
if(ls(id))ls(id)=copy_node(ls(id));
if(rs(id))rs(id)=copy_node(rs(id));
if(ls(id))tr[ls(id)].lz^=1;
if(rs(id))tr[rs(id)].lz^=1;
swap(ls(id),rs(id));
tr[id].lz=0;
}
void pushup(int id)
{
tr[id].size=tr[ls(id)].size+tr[rs(id)].size+1;
tr[id].sum=tr[ls(id)].sum+tr[rs(id)].sum+tr[id].val;
}
void sp(int id,int k,int &x,int &y)
{
if(!id)
{
x=y=0;return;
}
pushdown(id);
if(tr[ls(id)].size<k)
{
x=copy_node(id);
sp(rs(x),k-tr[ls(x)].size-1,rs(x),y);
pushup(x);
}
else
{
y=copy_node(id);
sp(ls(y),k,x,ls(y));
pushup(y);
}
}
int marge(int x,int y)
{
if(!x||!y)return x+y;
pushdown(x);pushdown(y);
if(tr[x].rk<tr[y].rk)
{
rs(x)=marge(rs(x),y);
pushup(x);
return x;
}
else
{
ls(y)=marge(x,ls(y));
pushup(y);
return y;
}
}
ll lans;
ll v,opt,p,val,l,r;
int main()
{
srand(time(NULL));
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
cin>>n;
for(ll i=1;i<=n;++i)
{
cin>>v>>opt;
rt[i]=rt[v];
if(opt==1)
{
cin>>p>>val;p^=lans;val^=lans;
int x=0,y=0;
sp(rt[i],p,x,y);
rt[i]=marge(marge(x,new_node(val)),y);
}
else if(opt==2)
{
cin>>p;p^=lans;
int x=0,y=0,z=0;
sp(rt[i],p-1,x,y);
sp(y,1,y,z);
rt[i]=marge(x,z);
}
else if(opt==3)
{
cin>>l>>r;l^=lans;r^=lans;
int x=0,y=0,z=0;
sp(rt[i],l-1,x,y);
sp(y,r-l+1,y,z);
y=copy_node(y);
tr[y].lz^=1;
rt[i]=marge(marge(x,y),z);
}
else
{
cin>>l>>r;l^=lans;r^=lans;
int x=0,y=0,z=0;
sp(rt[i],l-1,x,y);
sp(y,r-l+1,y,z);
lans=tr[y].sum;
cout<<lans<<'\n';
rt[i]=marge(x,marge(y,z));
}
}
}
结果MLE了一个点
然后我将 copy_node 函数中的 tr[cnt].rk=rand(); 注释掉,就AC了。
蒟蒻认为 copy_node后应该重新对随机值进行赋值以保证随机性,可是不重新赋值反而不会MLE,非常不理解,求大佬帮助。