网上有许多题,就是给定一个序列,要你支持几种操作:A、B、C、D。一看另一道题,又是一个序列 要支持几种操作:D、C、B、A。尤其是我们这里的某人,出模拟试题,居然还出了一道这样的,真是没技术含量……这样 我也出一道题,我出这一道的目的是为了让大家以后做这种题目有一个“库”可以依靠,没有什么其他的意思。这道题目 就叫序列终结者吧。 【问题描述】 给定一个长度为N的序列,每个序列的元素是一个整数(废话)。要支持以下三种操作: 1. 将[L,R]这个区间内的所有数加上V。 2. 将[L,R]这个区间翻转,比如1 2 3 4变成4 3 2 1。 3. 求[L,R]这个区间中的最大值。 最开始所有元素都是0。
第一行两个整数N,M。M为操作个数。 以下M行,每行最多四个整数,依次为K,L,R,V。K表示是第几种操作,如果不是第1种操作则K后面只有两个数。
#include
#include
#include
using namespace std;
const int N=50005;
const int inf=1e9+7;
int n,m,rt,cnt,mx[N],add[N],sz[N],rev[N],ch[N][2],fa[N],val[N],a[N];
void pushup(int x)
{
sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+1;
mx[x]=val[x];
if(ch[x][0])
mx[x]=max(mx[x],mx[ch[x][0]]);
if(ch[x][1])
mx[x]=max(mx[x],mx[ch[x][1]]);
}
void pushdown(int x)
{
if(rev[x])
{
rev[ch[x][0]]^=1,rev[ch[x][1]]^=1;
swap(ch[x][0],ch[x][1]);
rev[x]=0;
}
if(add[x])
{
if(ch[x][0])
add[ch[x][0]]+=add[x],mx[ch[x][0]]+=add[x],val[ch[x][0]]+=add[x];
if(ch[x][1])
add[ch[x][1]]+=add[x],mx[ch[x][1]]+=add[x],val[ch[x][1]]+=add[x];
add[x]=0;
}
}
int build(int l,int r,int f)
{
if(l>r)
return 0;
int mid=(l+r)/2;
int x=++cnt;
ch[x][0]=build(l,mid-1,x);
ch[x][1]=build(mid+1,r,x);
fa[x]=f;
val[x]=a[mid];
pushup(x);
return x;
}
void rotate(int x,int &k)
{
int y=fa[x],z=fa[y],lc=ch[y][1]==x,rc=lc^1;
if(k==y)
k=x;
else
ch[z][ch[z][1]==y]=x;
fa[x]=z,fa[y]=x,fa[ch[x][rc]]=y;
ch[y][lc]=ch[x][rc],ch[x][rc]=y;
pushup(y),pushup(x);
}
void splay(int x,int &k)
{
while(x!=k)
{
int y=fa[x],z=fa[y];
if(y!=k)
{
if((ch[y][0]==x)^(ch[z][0]==y))
rotate(x,k);
else
rotate(y,k);
}
rotate(x,k);
}
}
void split(int x,int y)
{
splay(x,rt),splay(y,ch[rt][1]);
}
int fnd(int x,int rnk)
{
pushdown(x);
if(rnk<=sz[ch[x][0]])
return fnd(ch[x][0],rnk);
if(rnk>sz[ch[x][0]]+1)
return fnd(ch[x][1],rnk-sz[ch[x][0]]-1);
return x;
}
int main()
{
scanf("%d%d",&n,&m);
a[1]=a[n+2]=-inf;
rt=build(1,n+2,0);
while(m--)
{
int opt,x,y,z;
scanf("%d",&opt);
if(opt==1)
{
scanf("%d%d%d",&x,&y,&z);
int p=fnd(rt,x),q=fnd(rt,y+2);
split(p,q);
add[ch[q][0]]+=z,mx[ch[q][0]]+=z,val[ch[q][0]]+=z;
}
if(opt==2)
{
scanf("%d%d",&x,&y);
int p=fnd(rt,x),q=fnd(rt,y+2);
split(p,q);
rev[ch[q][0]]^=1;
}
if(opt==3)
{
scanf("%d%d",&x,&y);
int p=fnd(rt,x),q=fnd(rt,y+2);
split(p,q);
printf("%d\n",mx[ch[q][0]]);
}
}
return 0;
}