萌新求助可持久化fhq-treap
查看原帖
萌新求助可持久化fhq-treap
577796
prokali楼主2023/8/18 11:06

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,非常不理解,求大佬帮助。

2023/8/18 11:06
加载中...