萌新求助fhq treap
查看原帖
萌新求助fhq treap
553625
scp020楼主2023/12/2 20:30
#include<bits/stdc++.h>
namespace fast_IO
{
	/*
	略
	*/
};
using namespace fast_IO;
int n,m,a[4000010];
std::string op;
template <typename T>
inline void swap(T &_x,T &_y)
{
	T tmp=_x;
	_x=_y,_y=tmp;
}
struct fhq_node
{
	int val,sum,w,siz;
	int maxi,lmax,rmax;
	int lazy,rev_lazy,flag; // lazy 是区间染色,rev_lazy 是区间翻转,flag 是是否有区间染色
	fhq_node *lc,*rc;
	inline fhq_node(int val)
	{
		this->val=sum=maxi=val,lmax=rmax=std::max(val,0),w=rand(),siz=1,lazy=rev_lazy=flag=0;
		lc=rc=nullptr;
	}
	inline void pushup()
	{
		siz=(lc==nullptr?0:lc->siz)+(rc==nullptr?0:rc->siz)+1;
		if(flag)
		{
			sum=lazy*siz;
			if(lazy>0) maxi=lmax=rmax=sum;
			else maxi=lazy,lmax=rmax=0;
		}else
		{
			sum=(lc==nullptr?0:lc->sum)+(rc==nullptr?0:rc->sum)+val;
			if(lc==nullptr && rc==nullptr) lmax=std::max(0,val);
			else if(lc==nullptr) lmax=std::max(0,val+rc->lmax);
			else if(rc==nullptr) lmax=std::max(lc->lmax,lc->sum+val);
			else lmax=std::max(lc->lmax,lc->sum+val+rc->lmax);
			if(lc==nullptr && rc==nullptr) rmax=std::max(0,val);
			else if(rc==nullptr) rmax=std::max(0,val+lc->rmax);
			else if(lc==nullptr) rmax=std::max(rc->rmax,rc->sum+val);
			else rmax=std::max(rc->rmax,rc->sum+val+lc->rmax);
			if(lc==nullptr && rc==nullptr) maxi=val;
			else if(lc==nullptr) maxi=std::max(rc->maxi,rc->lmax+val);
			else if(rc==nullptr) maxi=std::max(lc->maxi,val+lc->rmax);
			else maxi=std::max(std::max(lc->maxi,rc->maxi),lc->rmax+val+rc->lmax);
			if(rev_lazy) swap(lc,rc);
		}
	}
	inline void pushdown()
	{
		if(rev_lazy)
		{
			swap(lc,rc);
			if(lc!=nullptr) lc->rev_lazy^=1,swap(lc->lmax,lc->rmax);
			if(rc!=nullptr) rc->rev_lazy^=1,swap(rc->lmax,rc->rmax);
			rev_lazy=0;
		}
		if(flag)
		{
			val=lazy;
			if(lc!=nullptr) lc->lazy=lazy,lc->flag=1,lc->pushup();
			if(rc!=nullptr) rc->lazy=lazy,rc->flag=1,rc->pushup();
			flag=0;
		}
	}
};
class fhq_treap
{
private:
	fhq_node *root;
	inline fhq_node *merge(fhq_node *l,fhq_node *r)
	{
		if(l==nullptr)
		{
			r->pushup();
			return r;
		}
		if(r==nullptr)
		{
			l->pushup();
			return l;
		}
		l->pushdown(),r->pushdown();
		if(l->w<r->w)
		{
			l->rc=merge(l->rc,r),l->pushup();
			return l;
		}else
		{
			r->lc=merge(l,r->lc),r->pushup();
			return r;
		}
	}
	inline std::pair<fhq_node *,fhq_node *> split(fhq_node *rt,const int &k)
	{
		std::pair<fhq_node *,fhq_node *> ret;
		if(rt==nullptr) return std::make_pair(nullptr,nullptr);
		rt->pushdown();
		int left=rt->lc==nullptr?0:rt->lc->siz;
		if(k<=left) ret=split(rt->lc,k),rt->lc=ret.second,rt->pushup(),ret.second=rt;
		else ret=split(rt->rc,k-left-1),rt->rc=ret.first,rt->pushup(),ret.first=rt;
		return ret;
	}
	// inline void print(fhq_node *rt)
	// {
	// 	if(rt->lc!=nullptr) print(rt->lc);
	// 	std::cout<<rt->val<<' ';
	// 	if(rt->rc!=nullptr) print(rt->rc);
	// }
public:
	// inline void print()
	// {
	// 	print(root),std::cout<<std::endl;
	// }
	inline void insert(const int &pos,const int val)
	{
		fhq_node *rt=new fhq_node(val);
		std::pair<fhq_node *,fhq_node *> a;
		a=split(root,pos),root=merge(merge(a.first,rt),a.second);
	}
	inline void del(const int &L,const int &R)
	{
		std::pair<fhq_node *,fhq_node *> a,b;
		a=split(root,R),b=split(a.first,L-1);
		root=merge(b.first,a.second);
	}
	inline void fix(const int &L,const int &R,const int &val)
	{
		std::pair<fhq_node *,fhq_node *> a,b;
		a=split(root,R),b=split(a.first,L-1);
		b.second->flag=1,b.second->lazy=val,b.second->pushup();
		root=merge(merge(b.first,b.second),a.second);
	}
	inline int ask(const int &L,const int &R)
	{
		std::pair<fhq_node *,fhq_node *> a,b;
		a=split(root,R),b=split(a.first,L-1);
		int ret=b.second->sum;
		root=merge(merge(b.first,b.second),a.second);
		return ret;
	}
	inline int ask_max()
	{
		return root->maxi;
	}
	inline void overturn(const int &L,const int &R)
	{
		std::pair<fhq_node *,fhq_node *> a,b;
		a=split(root,R),b=split(a.first,L-1);
		b.second->rev_lazy^=1,swap(b.second->lmax,b.second->rmax);
		root=merge(merge(b.first,b.second),a.second);
	}
};
fhq_treap tree;
inline void fileIO(std::string filename)
{
	std::string I=filename+".in",O=filename+".out";
	freopen(I.c_str(),"r",stdin);
	freopen(O.c_str(),"w",stdout);
}
int main()
{
	// fileIO("example");
	in>>n>>m;
	for(int i=1,x;i<=n;i++) in>>x,tree.insert(i,x);
	for(int i=1,pos,tot,val;i<=m;i++)
	{
		in>>op;
		if(op=="INSERT")
		{
			in>>pos>>tot;
			for(int j=1;j<=tot;j++) in>>a[j];
			for(int j=tot;j;j--) tree.insert(pos,a[j]);
		}else if(op=="DELETE") in>>pos>>tot,tree.del(pos,pos+tot-1);
		else if(op=="MAKE-SAME") in>>pos>>tot>>val,tree.fix(pos,pos+tot-1,val);
		else if(op=="REVERSE") in>>pos>>tot,tree.overturn(pos,pos+tot-1);
		else if(op=="GET-SUM") in>>pos>>tot,out<<tree.ask(pos,pos+tot-1)<<'\n';
		else out<<tree.ask_max()<<'\n';
		// tree.print();
	}
	fwrite(Ouf,1,p3-Ouf,stdout),fflush(stdout);
	return 0;
}
2023/12/2 20:30
加载中...