萌新刚学平衡树,0pts求条
  • 板块灌水区
  • 楼主lfxxx_
  • 当前回复1
  • 已保存回复1
  • 发布时间2024/10/31 13:18
  • 上次更新2024/10/31 18:50:29
查看原帖
萌新刚学平衡树,0pts求条
795344
lfxxx_楼主2024/10/31 13:18

P2402

#include<bits/stdc++.h>
#define int long long 
using namespace std;
const int N=5e5+5,inf=0x3f3f3f3f;
mt19937 rng(time(0));
stack<int>s;
int root,tot;
struct node{
	int val,pri,ls,rs,sz;
	int qz,hz,maxn,sum;
	int tag,rev;
}tr[N]; 
int New(int x)
{
	int res=-1;
	if(!s.empty())
		res=s.top(),s.pop();
	else
		res=++tot;
	tr[res].val=tr[res].sum=tr[res].qz=tr[res].hz=x;
	tr[res].maxn=max(0LL,x);
	tr[res].pri=rng();
	tr[res].tag=inf;
	tr[res].ls=tr[res].rs=tr[res].rev=0;
	tr[res].sz=1;
	return res;
}
void pushup(int p)
{
	tr[p].sz=1;
	tr[p].sum=tr[p].qz=tr[p].hz=tr[p].maxn=tr[p].val;
	if(tr[p].ls)
	{
		tr[p].sz+=tr[tr[p].ls].sz;
		tr[p].qz=tr[tr[p].ls].qz;
		tr[p].sum+=tr[tr[p].ls].sum;
		tr[p].maxn=max(tr[p].maxn,tr[tr[p].ls].maxn); 
	}
	if((!tr[p].ls||tr[tr[p].ls].qz==tr[tr[p].ls].sum)&&tr[p].rs)
		tr[p].qz+=max(0LL,tr[tr[p].rs].qz);
	if(tr[p].rs)
	{
		tr[p].sz+=tr[tr[p].rs].sz;
		tr[p].hz=tr[tr[p].rs].hz;
		tr[p].sum+=tr[tr[p].rs].sum;
		tr[p].maxn=max(tr[p].maxn,tr[tr[p].rs].maxn); 
	}
	if((!tr[p].rs||tr[tr[p].rs].hz==tr[tr[p].rs].sum)&&tr[p].ls)
		tr[p].qz+=max(0LL,tr[tr[p].ls].hz);
	if(tr[p].ls&&tr[p].rs)
		tr[p].maxn=max(tr[p].maxn,tr[tr[p].ls].hz+tr[tr[p].rs].qz);
	tr[p].maxn=max(0LL,tr[p].maxn);
}
void addtag(int p,int d)
{
	tr[p].sum=tr[p].sz*d;
	tr[p].qz=tr[p].hz=(d>=0?tr[p].sz:1)*d;
	tr[p].maxn=max(0LL,tr[p].sz*d);
	tr[p].tag=d;
}
void pushdown(int p)
{
	if(tr[p].rev)
	{
		swap(tr[p].ls,tr[p].rs);
		if(tr[p].ls)tr[tr[p].ls].rev^=1;
		if(tr[p].rs)tr[tr[p].rs].rev^=1;
		tr[p].rev=0;
	}
	if(tr[p].tag!=inf)
	{
		if(tr[p].ls)addtag(tr[p].ls,tr[p].tag);
		if(tr[p].rs)addtag(tr[p].rs,tr[p].tag);
		tr[p].tag=inf;
	}
}
void split(int p,int k,int &L,int &R)
{
	if(!p)
	{
		L=R=0;
		return ;
	}
	pushdown(p);
	if(tr[tr[p].ls].sz<k)
	{
		L=p;
		split(tr[p].rs,k-tr[tr[p].ls].sz-1,tr[p].rs,R);
	}
	else
	{
		R=p;
		split(tr[p].ls,k,L,tr[p].ls);
	}
	pushup(p);
}
int merge(int L,int R)
{
	if(!L||!R)
		return L+R;
	if(tr[L].pri<=tr[R].pri)
	{
		pushdown(L); 
		tr[L].rs=merge(tr[L].rs,R);
		pushup(L);
		return L;
	}
	pushdown(R);
	tr[R].ls=merge(L,tr[R].ls);
	pushup(R);
	return R;
}
void del(int p)
{
	if(!p)
		return ;
	s.emplace(p);
	del(tr[p].ls);
	del(tr[p].rs); 
}
signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	int n,m;
	cin>>n>>m;
	for(int i=1;i<=n;++i)
	{
		int x;
		cin>>x;
		root=merge(root,New(x));
	}
	while(m--)
	{
		string op;
		cin>>op;
		if(op=="INSERT")
		{ 
			int pos,len,L,R;
			cin>>pos>>len;
			split(root,pos,L,R);
			for(int i=1;i<=len;++i)
			{
				int x;
				cin>>x;
				L=merge(L,New(x));
			}
			root=merge(L,R);
		}
		if(op=="DELETE")
		{
			int pos,len,L,R,p;
			cin>>pos>>len;
			split(root,pos-1,L,R);
			split(R,len,R,p);
			root=merge(L,p);
			del(R);	
		}
		if(op=="MAKE-SAME")
		{
			int pos,len,val,L,R,p;
			cin>>pos>>len>>val;
			split(root,pos-1,L,R);
			split(R,len,R,p);
			addtag(R,val);
			root=merge(L,merge(R,p));
		}
		if(op=="REVERSE")
		{
			int pos,len,L,R,p;
			cin>>pos>>len;
			split(root,pos-1,L,R);
			split(R,len,R,p);
			tr[R].rev^=1;
			root=merge(L,merge(R,p));
		}
		if(op=="GET-SUM")
		{
			int pos,len,L,R,p;
			cin>>pos>>len;
			split(root,pos-1,L,R);
			split(R,len,R,p);
			cout<<tr[R].sum<<'\n';
			root=merge(L,merge(R,p));
		}
		if(op=="MAX-SUM")
			cout<<tr[root].maxn<<'\n';
	}
}
2024/10/31 13:18
加载中...