bzoj1251 序列终结者
题意:
有一个长度为n的序列,初始情况下每个数的值为0
接下来有m次操作,每次操作为下面三种的其中一种:
(1,L,R,V),将区间[L,R]内的每个数加上V
(2,L,R),将区间[L,R]翻转
(3,L,R),输出[L,R]的最大值
数据范围:n<=5e4,m<=1e5
code:
#include<bits/stdc++.h>
using namespace std;
const int maxm=1e5+5;
const int inf=-1e9;
struct Spaly{
struct Node{
int val,Max,add,Size,son[2];
bool rev;
void init(int _val){
val=Max=_val;
Size=1;
add=rev=son[0]=son[1]=0;
}
}T[maxm];
int fa[maxm],root;
void pushup(int x){
T[x].Max=T[x].val,T[x].Size=1;
if(T[x].son[0]){
T[x].Max=max(T[x].Max,T[T[x].son[0]].Max);
T[x].Size+=T[T[x].son[0]].Size;
}
if(T[x].son[1]){
T[x].Max=max(T[x].Max,T[T[x].son[1]].Max);
T[x].Size+=T[T[x].son[1]].Size;
}
}
void pushdown(int x){
if(x==0)return ;
if(T[x].add){
if(T[x].son[0]){
T[T[x].son[0]].val+=T[x].add;
T[T[x].son[0]].Max+=T[x].add;
T[T[x].son[0]].add+=T[x].add;
}
if(T[x].son[1]){
T[T[x].son[1]].val+=T[x].add;
T[T[x].son[1]].Max+=T[x].add;
T[T[x].son[1]].add+=T[x].add;
}
T[x].add=0;
}
if(T[x].rev){
if(T[x].son[0])T[T[x].son[0]].rev^=1;
if(T[x].son[1])T[T[x].son[1]].rev^=1;
swap(T[x].son[0],T[x].son[1]);
T[x].rev=0;
}
}
void Rotate(int x,int kind){//kind=0左旋,=1右旋
int y=fa[x],z=fa[y];
T[y].son[!kind]=T[x].son[kind],fa[T[x].son[kind]]=y;
T[x].son[kind]=y,fa[y]=x;
T[z].son[T[z].son[1]==y]=x,fa[x]=z;
pushup(y);
}
void Splay(int x,int goal){//将x旋转到goal位置
if(x==goal)return ;
while(fa[x]!=goal){
int y=fa[x],z=fa[y];
pushdown(z),pushdown(y),pushdown(x);
int rx=T[y].son[0]==x,ry=T[z].son[0]==y;//rx,ry,=0左儿子,=1右儿子
if(z==goal)Rotate(x,rx);
else{
if(rx==ry)Rotate(y,ry);
else Rotate(x,rx);
Rotate(x,ry);
}
}
pushup(x);
if(goal==0)root=x;
}
int Select(int pos){//找pos的位置
int u=root;
pushdown(u);
while(T[T[u].son[0]].Size!=pos){
if(pos<T[T[u].son[0]].Size)u=T[u].son[0];//左边
else{//右边
pos-=T[T[u].son[0]].Size+1;
u=T[u].son[1];
}
pushdown(u);
}
return u;
}
void update(int L,int R,int val){
int u=Select(L-1),v=Select(R+1);
Splay(u,0);
Splay(v,u);
T[T[v].son[0]].Max+=val;
T[T[v].son[0]].val+=val;
T[T[v].son[0]].add+=val;
}
void Reverse(int L,int R){
int u=Select(L-1),v=Select(R+1);
Splay(u,0);
Splay(v,u);
T[T[v].son[0]].rev^=1;
}
int query(int L,int R){
int u=Select(L-1),v=Select(R+1);
Splay(u,0);
Splay(v,u);
return T[T[v].son[0]].Max;
}
int build(int L,int R){
if(L>R)return 0;
if(L==R)return L;
int mid=(L+R)/2,sL,sR;
T[mid].son[0]=sL=build(L,mid-1);
T[mid].son[1]=sR=build(mid+1,R);
fa[sL]=fa[sR]=mid;
pushup(mid);
return mid;
}
void init(int n){
T[0].init(-inf),T[1].init(-inf),T[n+2].init(-inf);
for(int i=2;i<=n+1;i++)T[i].init(0);
root=build(1,n+2),fa[root]=0;
fa[0]=0,T[0].son[1]=root,T[0].Size=0;
}
}T;
int n,m;
signed main(){
scanf("%d%d",&n,&m);
T.init(n);
while(m--){
int d;scanf("%d",&d);
if(d==1){//区间加
int l,r,v;scanf("%d%d%d",&l,&r,&v);
T.update(l,r,v);
}else if(d==2){//区间翻转
int l,r;scanf("%d%d",&l,&r);
T.Reverse(l,r);
}else if(d==3){//区间最值
int l,r;scanf("%d%d",&l,&r);
int ans=T.query(l,r);
printf("%d\n",ans);
}
}
return 0;
}