序列终结者
要求写一个数据结构,支持区间加,区间翻转,查询区间最大值。
没有动态插入和动态删除我不是很认可,还什么“序列终结者”,常用的都没有包含完。
就是板子。要注意的是一个点的最大值等于左右孩子的最大值和自己的data再取一次最大值(我也不知道当时脑子是怎么抽掉的)。另外就是pushup和pushnow要判断一下是不是对0号节点进行操作。对0号节点动刀子是大大的不可以的。其它就是pushup的时候要判左右孩子是不是0(或者把它maxn赋值成-maxn也可以)。由于脑子抽了很是调了一会。
code:
#include<bits/stdc++.h>
//#define zczc
const int N=50010;
using namespace std;
inline void read(int &wh){
wh=0;int f=1;char w=getchar();
while(w<'0'||w>'9'){if(w=='-')f=-1;w=getchar();}
while(w<='9'&&w>='0'){wh=wh*10+w-'0';w=getchar();}
wh*=f;return;
}
inline int max(int s1,int s2){
return s1<s2?s2:s1;
}
inline void swap(int &s1,int &s2){
int s3=s1;s1=s2;s2=s3;return;
}
int m,n;
#define lc t[x].ch[0]
#define rc t[x].ch[1]
struct node{
int f,ch[2];
int size,data,maxn;
int add;bool lazy;
}t[N];
int root;
inline void pushup(int x){
if(x==0)return;
t[x].maxn=max(t[x].data,max(t[lc].maxn,t[rc].maxn));
t[x].size=t[lc].size+t[rc].size+1;
}
inline void pushnow(int x,int add,bool lazy){
if(x==0)return;
if(lazy)t[x].lazy=t[x].lazy^1,swap(lc,rc);
if(add)t[x].add+=add,t[x].data+=add,t[x].maxn+=add;
}
inline void pushdown(int x){
pushnow(lc,t[x].add,t[x].lazy);
pushnow(rc,t[x].add,t[x].lazy);
t[x].add=t[x].lazy=0;
}
inline int build(int l,int r,int fa){
if(l>r)return 0;
int x=l+r+1>>1;
t[x].size=1;t[x].f=fa;
if(l==r)return l;
lc=build(l,x-1,x);rc=build(x+1,r,x);
pushup(x);return x;
}
inline int find(int x,int kk){
pushdown(x);
if(t[lc].size>=kk)return find(lc,kk);
if(t[lc].size+1==kk)return x;
return find(rc,kk-t[lc].size-1);
}
inline void rotate(int x){
int y=t[x].f;int z=t[y].f;
int kk=t[y].ch[1]==x;int cd=t[x].ch[kk^1];
if(z)t[z].ch[t[z].ch[1]==y]=x;t[x].f=z;
t[cd].f=y;t[y].ch[kk]=cd;
t[x].ch[kk^1]=y;t[y].f=x;
pushup(y);pushup(x);
if(y==root)root=x;return;
}
inline void splay(int x,int rt){
while(t[x].f^rt){
int y=t[x].f;int z=t[y].f;
if(z^rt)(t[z].ch[1]==y)^(t[y].ch[1]==x)?rotate(x):rotate(y);
rotate(x);
}
if(rt==0)root=x;
}
#undef lc
#undef rc
signed main(){
#ifdef zczc
freopen("in.txt","r",stdin);
#endif
read(m);read(n);root=build(1,m+2,0);
int op,l,r,data;t[0].maxn=-0x7fffffff;
while(n--){
read(op);read(l);read(r);l++;r++;
int s1=find(root,l-1),s2=find(root,r+1);
splay(s1,0);splay(s2,s1);
int x=t[s2].ch[0];
if(op==1){
read(data);pushnow(x,data,false);
pushup(s2);pushup(s1);
}
if(op==2){
pushnow(x,0,true);
pushup(s2);pushup(s1);
}
if(op==3)printf("%d\n",t[x].maxn);
}
return 0;
}
一如既往,万事胜意