题解序列终结者
Posted h-lka
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了题解序列终结者相关的知识,希望对你有一定的参考价值。
\(splay\)维护区间加,区间翻转,区间\(max\).
维护标记,区间加标记和区间翻转标记。记住两个是同级的,都要更新。
更详细的解释请参考笔者的题解:数列。
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
const int MAXN=5e5+10;
const int inf=2e9;
int n,m,id,rt,vx[MAXN];
struct Splay_Tree
int val,fa,maxn,ch[2];
int tag,siz,rev;
tr[MAXN];
inline void pushup(int x)
tr[x].maxn=max(tr[tr[x].ch[0]].maxn,max(tr[tr[x].ch[1]].maxn,tr[x].val));
tr[x].siz=tr[tr[x].ch[0]].siz+tr[tr[x].ch[1]].siz+1;
inline int build(int l,int r,int f)
if(l>r)return 0;int x=++id,mid=l+r>>1;
tr[x].fa=f;tr[x].val=tr[x].maxn=vx[mid];
tr[x].ch[0]=build(l,mid-1,x),tr[x].ch[1]=build(mid+1,r,x);
pushup(x);return x;
inline void rotate(int x)
int y=tr[x].fa,z=tr[y].fa,k=tr[y].ch[1]==x;
tr[z].ch[tr[z].ch[1]==y]=x;tr[x].fa=z;
tr[y].ch[k]=tr[x].ch[k^1];tr[tr[x].ch[k^1]].fa=y;
tr[x].ch[k^1]=y;tr[y].fa=x;pushup(y);pushup(x);
inline void splay(int x,int g)
while(tr[x].fa!=g)
int y=tr[x].fa,z=tr[y].fa;
if(z!=g)
(tr[y].ch[0]==x)^(tr[z].ch[0]==y)?rotate(x):rotate(y);
rotate(x);
if(!g)rt=x;
inline void pushdown(int x)
int lc=tr[x].ch[0],rc=tr[x].ch[1];
if(tr[x].tag)
int p=tr[x].tag;
if(lc)
tr[lc].tag+=p;
tr[lc].val+=p;
tr[lc].maxn+=p;
if(rc)
tr[rc].tag+=p;
tr[rc].val+=p;
tr[rc].maxn+=p;
tr[x].tag=0;
if(tr[x].rev)
tr[x].rev=0;
tr[lc].rev^=1;tr[rc].rev^=1;
swap(tr[lc].ch[0],tr[lc].ch[1]);
swap(tr[rc].ch[0],tr[rc].ch[1]);
inline int Kth(int x)
int u=rt;
// if(!x)return 0;
while(u)
pushdown(u);
int y=tr[u].ch[0];
if(tr[y].siz>=x)u=y;
else
x-=tr[y].siz+1;
if(!x)return u;
u=tr[u].ch[1];
return 0;
inline void change_R(int x,int y)
int L=Kth(x),R=Kth(y+2);
splay(L,0);splay(R,L);
int g=tr[R].ch[0];
tr[g].rev^=1;swap(tr[g].ch[0],tr[g].ch[1]);
pushup(R);pushup(L);
inline void change_A(int x,int y,int v)
int L=Kth(x),R=Kth(y+2);
splay(L,0);splay(R,L);
int g=tr[R].ch[0];
tr[g].tag+=v;tr[g].val+=v;tr[g].maxn+=v;
pushup(R);pushup(L);
inline int Get(int x,int y)
int L=Kth(x),R=Kth(y+2);
splay(L,0);splay(R,L);
return tr[tr[R].ch[0]].maxn;
int main()
scanf("%d%d",&n,&m);
tr[0].maxn=vx[1]=vx[n+2]=-inf;rt=build(1,n+2,0);
while(m--)
int opt,L,R,X;
scanf("%d%d%d",&opt,&L,&R);
if(opt==1)
scanf("%d",&X);
change_A(L,R,X);
else if(opt==2)
change_R(L,R);
else if(opt==3)
printf("%d\n",Get(L,R));
return 0;
以上是关于题解序列终结者的主要内容,如果未能解决你的问题,请参考以下文章