Description
网上有许多题,就是给定一个序列,要你支持几种操作: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。
【题目分析】
Splay维护区间操作。
刚开始看错题目了 - -#
【代码】
#include <cmath>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <map>
#include <set>
#include <queue>
#include <iostream>
#include <algorithm>
using namespace std;
int read()
{
int x=0,f=1; char ch=getchar();
while (ch<'0'||ch>'9') { if (ch=='-') f=-1; ch=getchar(); }
while (ch>='0'&&ch<='9') { x=x*10+ch-'0'; ch=getchar(); }
return x*f;
}
#define ll long long
#define inf (0x3f3f3f3f)
#define maxn 50005
int x,y,f,rt,l,r;
int tot,data[maxn],siz[maxn],fa[maxn];
int ch[maxn][2],lar[maxn],tag[maxn],rev[maxn];
void update(int k)
{
lar[k]=max(max(lar[ch[k][0]],lar[ch[k][1]]),data[k]);
siz[k]=siz[ch[k][0]]+siz[ch[k][1]]+1;
}
void build(int l,int r,int lst)
{
if (l>r) return ;
if (l==r)
{
fa[l]=lst;
siz[l]=1;
if (l<lst) ch[lst][0]=l;
else ch[lst][1]=l;
return ;
}
int mid=(l+r)/2;
build(l,mid-1,mid); build (mid+1,r,mid);
fa[mid]=lst;
update(mid);
if (mid<lst) ch[lst][0]=mid;
else ch[lst][1]=mid;
}
void pushdown(int k)
{
if (tag[k])
{
if (ch[k][0])
{
tag[ch[k][0]]+=tag[k];
lar[ch[k][0]]+=tag[k];
data[ch[k][0]]+=tag[k];
}
if (ch[k][1])
{
tag[ch[k][1]]+=tag[k];
lar[ch[k][1]]+=tag[k];
data[ch[k][1]]+=tag[k];
}
tag[k]=0;
}
if (rev[k])
{
if (ch[k][0]) rev[ch[k][0]]^=1;
if (ch[k][1]) rev[ch[k][1]]^=1;
rev[k]=0;
swap(ch[k][0],ch[k][1]);
}
return ;
}
int find(int k,int x)
{
if (tag[k]||rev[k]) pushdown(k);
if (x<=siz[ch[k][0]]) return find(ch[k][0],x);
if (x==1+siz[ch[k][0]]) return k;
return find(ch[k][1],x-siz[ch[k][0]]-1);
}
void rot(int x,int &k)
{
int y=fa[x],z=fa[y],l,r;
if (ch[y][0]==x) l=0;
else l=1;
r=l^1;
if (y==k) k=x;
else
{
if (ch[z][0]==y) ch[z][0]=x;
else ch[z][1]=x;
}
fa[x]=z;
fa[y]=x;
fa[ch[x][r]]=y;
ch[y][l]=ch[x][r];
ch[x][r]=y;
update(y); update(x);
}
void splay(int x,int &k)
{
while (x!=k)
{
int y=fa[x],z=fa[y];
if (y!=k)
{
if ((ch[z][0]==y)^(ch[y][0]==x)) rot(x,k);
else rot(y,k);
}
rot(x,k);
}
}
int main()
{
lar[0]=-inf;
int n=read(),m=read();
build(1,n+2,0);
rt=(n+3)>>1;
while (m--)
{
int opt=read();
switch (opt)
{
case 1:
l=read(),r=read(),f=read();
x=find(rt,l); y=find(rt,r+2);
splay(x,rt);
splay(y,ch[x][1]);
tag[ch[y][0]]+=f;
lar[ch[y][0]]+=f;
data[ch[y][0]]+=f;
break;
case 2:
l=read(),r=read();
x=find(rt,l); y=find(rt,r+2);
splay(x,rt);
splay(y,ch[x][1]);
rev[ch[y][0]]^=1;
break;
case 3:
l=read(),r=read();
x=find(rt,l); y=find(rt,r+2);
splay(x,rt);
splay(y,ch[x][1]);
printf("%d\n",lar[ch[y][0]]);
break;
}
}
}