(板子)平衡樹維護序列

把之前文藝平衡樹的板子稍微改了一下用來做別的板子題(

luoguP4146 序列終結者

code: (讀入等略)

const int maxn=50010;
int tot,rt;
struct node{int l,r,val,key,siz,maxx,add,rev;}tree[maxn];
inline void newnode(int &x,int val)
{x=++tot;tree[x]=(node){0,0,val,rand(),1,val,0,0};}
inline void pushup(int x)
{
	tree[x].siz=tree[tree[x].l].siz+tree[tree[x].r].siz+1;
	tree[x].maxx=tree[x].val;
	if(tree[x].l)tree[x].maxx=max(tree[x].maxx,tree[tree[x].l].maxx);
	if(tree[x].r)tree[x].maxx=max(tree[x].maxx,tree[tree[x].r].maxx);
}
inline void pushrev(int x){tree[x].rev^=1;}
inline void pushadd(int x,int k)
{
	tree[x].add+=k;
	tree[x].val+=k;
	tree[x].maxx+=k;
}
inline void pushdown(int x)
{
	if(tree[x].rev)
	{
		if(tree[x].l)pushrev(tree[x].l);
		if(tree[x].r)pushrev(tree[x].r);
		swap(tree[x].l,tree[x].r);
		tree[x].rev=0;
	}
	if(tree[x].add)
	{
		if(tree[x].l)pushadd(tree[x].l,tree[x].add);
		if(tree[x].r)pushadd(tree[x].r,tree[x].add);
		tree[x].add=0;
	}
}
inline void split(int x,int siz,int &rx,int &ry)
{
	if(!x){rx=ry=0;return;}
	pushdown(x);
	if(tree[tree[x].l].siz<siz)
	{
		rx=x;
		split(tree[x].r,siz-tree[tree[x].l].siz-1,tree[x].r,ry);
	}
	else
	{
		ry=x;
		split(tree[x].l,siz,rx,tree[x].l);
	}
	pushup(x);
}
inline int merge(int x,int y)
{
	pushdown(x);pushdown(y);
	if(!x||!y)return x+y;
	if(tree[x].key<tree[y].key)
	{
		tree[x].r=merge(tree[x].r,y);
		pushup(x);return x;
	}
	else
	{
		tree[y].l=merge(x,tree[y].l);
		pushup(y);return y;
	}
}
inline void ins(int pos,int val)
{
	int now,x,y;
	split(rt,pos,x,y);newnode(now,val);
	rt=merge(merge(x,now),y);
}
inline void modify_rev(int l,int r)
{
	int x,y,z;
	split(rt,l-1,x,y);
	split(y,r-l+1,y,z);
	pushrev(y);
	rt=merge(merge(x,y),z);
}
inline void modify_add(int l,int r,int k)
{
	int x,y,z;
	split(rt,l-1,x,y);
	split(y,r-l+1,y,z);
	pushadd(y,k);
	rt=merge(merge(x,y),z);
}
inline int query(int l,int r)
{
	int x,y,z;
	split(rt,l-1,x,y);
	split(y,r-l+1,y,z);
	int now=tree[y].maxx;
	rt=merge(merge(x,y),z);
	return now;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章