为什么我的FHQ_Treap会因为随机出的结构不同而导致答案不同
查看原帖
为什么我的FHQ_Treap会因为随机出的结构不同而导致答案不同
556042
Iratis楼主2022/4/11 22:08
#include<iostream>
#include<iomanip>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<cstdlib>
#include<time.h>
using namespace std;
#define P pair<int,int>
const int N=4000005,inf=0x7fffffff;
int n,Q;
struct Treap
{
	int ch[N][2],siz[N],rd[N],root,rev[N],add[N];
	int sum[N],lmax[N],rmax[N],dat[N],num[N];
	void pushup(int v)
	{
		siz[v]=siz[ch[v][0]]+siz[ch[v][1]]+1;
		sum[v]=sum[ch[v][0]]+sum[ch[v][1]]+num[v];
		lmax[v]=max(lmax[ch[v][0]],sum[ch[v][0]]+num[v]+lmax[ch[v][1]]);
		rmax[v]=max(rmax[ch[v][1]],sum[ch[v][1]]+num[v]+rmax[ch[v][0]]);
		dat[v]=max(max(dat[ch[v][0]],dat[ch[v][1]]),rmax[ch[v][0]]+num[v]+lmax[ch[v][1]]);
	}
	void pushdown(int v)
	{
		if(!v)return ;
		if(rev[v])
		{
			swap(lmax[v],rmax[v]);
			swap(lmax[ch[v][0]],lmax[ch[v][1]]);
			swap(rmax[ch[v][0]],rmax[ch[v][1]]);
			swap(ch[v][0],ch[v][1]);
			rev[ch[v][0]]^=1,rev[ch[v][1]]^=1,rev[v]=0;
		}
		if(add[v]!=inf)
		{
			num[v]=add[v];
			sum[v]=lmax[v]=rmax[v]=dat[v]=add[v]*siz[v];
			add[ch[v][0]]=add[v],add[ch[v][1]]=add[v];
			add[v]=inf;
		}
	}
	P split(int x,int k)
	{
		if(!x)return P(0,0);
		pushdown(x);
		P tmp;
		if(k>siz[ch[x][0]])
		{
			tmp=split(ch[x][1],k-siz[ch[x][0]]-1);
			ch[x][1]=tmp.first,pushup(x);
			return P(x,tmp.second);
		}
		else
		{
			tmp=split(ch[x][0],k);
			ch[x][0]=tmp.second,pushup(x);
			return P(tmp.first,x);
		}
	}
	int merge(int a,int b)
	{
		if(!a||!b)return a+b;
		pushdown(a),pushdown(b);
		if(rd[a]<rd[b])
		{
			ch[a][1]=merge(ch[a][1],b);
			pushup(a);return a;
		}
		else
		{
			ch[b][0]=merge(a,ch[b][0]);
			pushup(b);return b;
		}
	}
	void insd(int i,int val)
	{
		siz[i]=1,rd[i]=rand()%inf;
		add[i]=inf,sum[i]=lmax[i]=rmax[i]=dat[i]=num[i]=val;
		root=merge(root,i);
	}
	void insx(int sz,int l)
	{
		int rt=0;
		for(int i=1;i<=sz;i++)
		{
			int x;
			n++;
			scanf("%d",&x);
			siz[n]=1,rd[n]=rand()%inf;
			add[n]=inf,sum[n]=lmax[n]=rmax[n]=dat[n]=num[n]=x;
			rt=merge(rt,n);
		}
		P L;
		L=split(root,l-1);
		root=merge(merge(L.first,rt),L.second);
	}
	void del(int l,int r)
	{
		P L,R;
		L=split(root,l-1);
		R=split(L.second,r-l+1);
		root=merge(L.first,R.second);
	}
	void make_same(int l,int r,int d)
	{
		P L,R;
		L=split(root,l-1);
		R=split(L.second,r-l+1);
		add[R.first]=d;
		R.first=merge(R.first,R.second);
		root=merge(L.first,R.first);
	}
	void rever(int l,int r)
	{
		P L,R;
		L=split(root,l-1);
		R=split(L.second,r-l+1);
		rev[R.first]^=1;
		R.first=merge(R.first,R.second);
		root=merge(L.first,R.first);
	}
	int get_sum(int l,int r)
	{
		P L,R;
		L=split(root,l-1);
		R=split(L.second,r-l+1);
		pushup(R.first);
		int ans=sum[R.first];
		R.first=merge(R.first,R.second);
		root=merge(L.first,R.first);
		return ans;
	}
	int max_sum(int l,int r)
	{
		P L,R;
		L=split(root,l-1);
		R=split(L.second,r-l+1);
		pushup(R.first);
		int ans=dat[R.first];
		R.first=merge(R.first,R.second);
		root=merge(L.first,R.first);
		return ans;
	}
	void print(int x)
	{
		if(!x)return ;
		print(ch[x][0]);
		printf("x:%d lmax:%d rmax:%d sum:%d num:%d dat:%d\n",x,ch[x][0],ch[x][1],sum[x],num[x],dat[x]);
		print(ch[x][1]);
	}
}tree;
signed main()
{
	scanf("%d%d",&n,&Q);
	srand(time(0));
	for(int i=1;i<=n;i++)
	{
		int x;
		scanf("%d",&x);
		tree.insd(i,x);
	}
	while(Q--)
	{
		char op[15];
		scanf("%s",op);
		if(op[0]=='I')
		{
			int pos,siz;
			scanf("%d%d",&pos,&siz);
			tree.insx(siz,pos+1);
		}
		else if(op[0]=='D')
		{
			int pos,tot;
			scanf("%d%d",&pos,&tot);
			tree.del(pos,pos+tot-1);
		}
		else if(op[0]=='M'&&op[2]=='K')
		{
			int pos,tot,c;
			scanf("%d%d%d",&pos,&tot,&c);
			tree.make_same(pos,pos+tot-1,c);
		}
		else if(op[0]=='R')
		{
			int pos,tot;
			scanf("%d%d",&pos,&tot);
			tree.rever(pos,pos+tot-1);
		}
		else if(op[0]=='G')
		{
			int pos,tot;
			scanf("%d%d",&pos,&tot);
			printf("%d\n",tree.get_sum(pos,pos+tot-1));
		}
		else
		{
			printf("%d\n",tree.max_sum(1,n));
		}
//		tree.print(tree.root);
	}
	return 0;
}
2022/4/11 22:08
加载中...