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。
Input
第一行两个整数N,M。M为操作个数。 以下M行,每行最多四个整数,依次为K,L,R,V。K表示是第几种操作,如果不是第1种操作则K后面只有两个数。
Output
对于每个第3种操作,给出正确的回答。
Sample Input
4 4
1 1 3 2
1 2 4 -1
2 1 3
3 2 4
Sample Output
2
题解:
- 区间加:直接把l,r找到然后打上标记即可
- 区间翻转:同上
- 区间max:每个点维护一个子树max值即可
又水了一个板子…
AC代码:
#pragma GCC optimize(2)
#include<bits/stdc++.h>
#include<ext/rope>
using namespace std;
using namespace __gnu_cxx;
typedef long long LL;
const int MAXN = 1e5+50;
const int MOD = 1e9+7;
const int INF = 0x3f3f3f3f;
struct node{
int son[2],fa,sz,val,mx,lazy,lz;
inline void init(int f,int v){ fa=f; val=mx=v; sz=1; lazy=lz=0; }
}t[MAXN];
int a[MAXN],root,tot,n,m;
inline int id(int x){ return x==t[t[x].fa].son[1]; }
inline void pushup(int x){
t[x].sz=t[t[x].son[0]].sz+t[t[x].son[1]].sz+1;
t[x].mx=t[x].val;
if(t[x].son[0]) t[x].mx=max(t[x].mx,t[t[x].son[0]].mx);
if(t[x].son[1]) t[x].mx=max(t[x].mx,t[t[x].son[1]].mx);
}
inline void pushdown(int x){
if(t[x].lz){
t[t[x].son[0]].lz+=t[x].lz; t[t[x].son[1]].lz+=t[x].lz;
t[t[x].son[0]].mx+=t[x].lz; t[t[x].son[1]].mx+=t[x].lz;
t[t[x].son[0]].val+=t[x].lz; t[t[x].son[1]].val+=t[x].lz;
t[x].lz=0;
}
if(t[x].lazy){
t[t[x].son[0]].lazy^=1; t[t[x].son[1]].lazy^=1;
t[x].lazy=0; swap(t[x].son[0],t[x].son[1]);
}
}
inline void rotate(int x){
int y=t[x].fa,z=t[y].fa,k=id(x);
t[z].son[id(y)]=x; t[x].fa=z;
t[y].son[k]=t[x].son[k^1]; t[t[x].son[k^1]].fa=y;
t[x].son[k^1]=y; t[y].fa=x;
pushup(y); pushup(x);
}
inline void splay(int x,int pos){
while(t[x].fa!=pos){
int y=t[x].fa,z=t[y].fa;
if(z!=pos) id(x)==id(y) ? rotate(y):rotate(x);
rotate(x);
}
if(!pos) root=x;
}
inline int build(int rt,int l,int r){
if(l>r) return 0; int mid=(l+r)>>1;
int u=++tot;
t[u].init(rt,a[mid]);
t[u].son[0]=build(u,l,mid-1); t[u].son[1]=build(u,mid+1,r);
pushup(u); return u;
}
inline int kth(int x){
int u=root;
while(1){
pushdown(u);
if(t[t[u].son[0]].sz>=x) u=t[u].son[0];
else{
x -= t[t[u].son[0]].sz+1;
if(!x) return u;
u=t[u].son[1];
}
}
}
signed main(){
#ifndef ONLINE_JUDGE
freopen("C:\\Users\\Administrator\\Desktop\\in.txt","r",stdin);
#endif // ONLINE_JUDGE
scanf("%d%d",&n,&m); a[1]=-INF,a[n+2]=INF;
root = build(0,1,n+2);
while(m--){
int op,l,r,v; scanf("%d%d%d",&op,&l,&r);
int ll=kth(l),rr=kth(r+2);
splay(ll,0); splay(rr,ll);
int k=t[t[root].son[1]].son[0];
if(op==1){
scanf("%d",&v);
t[k].mx+=v; t[k].val+=v; t[k].lz+=v;
pushup(t[root].son[1]); pushup(root);
}else if(op==2){
t[k].lazy^=1;
}else if(op==3){
printf("%d\n",t[k].mx);
}
}
return 0;
}