序列终结者

fhq treap+lazy标记

就是几个题拼起来而已

#include"cstdio"
#include"cstring"
#include"iostream"
#include"algorithm"
#include"ctime"
using namespace std;

const int MAXN=5e4+5;
const int INF=0x3f3f3f3f;

int n,m,root,cnt;
int siz[MAXN],val[MAXN],mx[MAXN],rev[MAXN],sn[2][MAXN],pls[MAXN];
bool tag[MAXN];

int cret()
{
	siz[++cnt]=1;
	rev[cnt]=rand();
	return cnt;
}

void pushdown(int v)
{
	if(!tag[v]&&!pls[v]||!v) return;
	if(tag[v]){
		swap(sn[0][v],sn[1][v]);
		tag[sn[0][v]]^=1;
		tag[sn[1][v]]^=1;
		tag[v]=0;
	}if(pls[v]){
		mx[sn[0][v]]+=pls[v];
		mx[sn[1][v]]+=pls[v];
		val[sn[0][v]]+=pls[v];
		val[sn[1][v]]+=pls[v];
		pls[sn[0][v]]+=pls[v];
		pls[sn[1][v]]+=pls[v];
		pls[v]=0;
	}return;
}

void pushup(int v)
{
	siz[v]=siz[sn[0][v]]+siz[sn[1][v]]+1;
	mx[0]=val[0]=-INF;
	mx[v]=max(max(mx[sn[0][v]],mx[sn[1][v]]),val[v]);
	return;
}

int un(int x,int y)
{
	if(!x||!y) return x|y;
	if(rev[x]<rev[y]){
		pushdown(x);
		sn[1][x]=un(sn[1][x],y);
		pushup(x);
		return x;
	}pushdown(y);
	sn[0][y]=un(x,sn[0][y]);
	pushup(y);
	return y;
}

void dro(int k,int v,int &x,int &y)
{
	if(!k){x=y=0;return;}
	pushdown(k);
	if(siz[sn[0][k]]<v) x=k,dro(sn[1][k],v-siz[sn[0][k]]-1,sn[1][k],y);
	else y=k,dro(sn[0][k],v,x,sn[0][k]);
	pushup(k);
	return;
}

void cadd(int l,int r,int v)
{
	int x,y,z;
	dro(root,l-1,x,y);
	dro(y,r-l+1,y,z);
	val[y]+=v;mx[y]+=v;pls[y]+=v;
	root=un(x,un(y,z));
	return;
}

void cdro(int l,int r)
{
	int x,y,z;
	dro(root,l-1,x,y);
	dro(y,r-l+1,y,z);
	tag[y]^=1;
	root=un(x,un(y,z));
	return;
}

int cask(int l,int r)
{
	int x,y,z,ans;
	dro(root,l-1,x,y);
	dro(y,r-l+1,y,z);
	pushdown(y);pushup(y);
	ans=max(mx[y],val[y]);
	root=un(x,un(y,z));
	return ans;
}

int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;++i) root=un(root,cret());
	while(m--){
		int p,l,r,v;
		scanf("%d%d%d",&p,&l,&r);
		if(p==1){int v;scanf("%d",&v);cadd(l,r,v);}
		else if(p==2) cdro(l,r);
		else printf("%d\n",cask(l,r));
	}return 0;
}
posted @ 2018-12-12 17:15  A·H  阅读(149)  评论(0编辑  收藏  举报