基本操作 翻转 成段加上一个数 求区间最值
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<queue>
#include<set>
#include<cstring>
#include<vector>
using namespace std;
#define L p->ch[0]
#define R p->ch[1]
#define KeyTree root->ch[1]->ch[0]
typedef long long LL;
const int maxn = 611111;
const int INF = 0x77ffffff;
struct Node {
int val, Max, add;
int sz;
bool rev;
Node *pre, *ch[2];
};
int a[maxn];
struct SplayTree {
Node *null, *root, data[maxn];
int cnt;
Node *NewNode(int x) {
Node *p = &data[cnt++];
p->val = p->Max = x;
p->sz = 1;
p->add = 0;
L=R=p->pre=null;
return p;
}
void pushup(Node *p) {
p->sz = (L->sz)+(R->sz) + 1;
p->Max=p->val;
if(L!=null) {
p->Max=max(p->Max,L->Max);
}
if(R!=null) {
p->Max=max(p->Max,R->Max);
}
}
void pushdown(Node *p) {
if(p==null) {
return;
}
if(p->rev) {
swap(L,R);
L->rev^=1;
R->rev^=1;
p->rev=0;
}
if(p->add) {
L->add+=p->add;
L->val+=p->add;
L->Max+=p->add;
R->add+=p->add;
R->val+=p->add;
R->Max+=p->add;
p->add=0;
}
}
void init() {
cnt=0;
null=NewNode(-INF);
null->sz=0;
root=NewNode(-INF);
root->ch[1]=NewNode(-INF);
root->ch[1]->pre=root;
pushup(root);
}
void rotate(Node *x,int c) {
Node *y=x->pre;
pushdown(y);
pushdown(x);
y->ch[!c]=x->ch[c];
if(x->ch[c]!=null) {
x->ch[c]->pre=y;
}
x->pre=y->pre;
if(y->pre!=null) {
int f=(y->pre->ch[1]==y);
y->pre->ch[f]=x;
}
x->ch[c]=y;
y->pre=x;
pushup(y);
}
void splay(Node *x,Node *f) {
pushdown(x);
while(x->pre!=f) {
if(x->pre->pre==f) {
rotate(x,x->pre->ch[0]==x);
} else {
Node *y=x->pre;
Node *z=y->pre;
if(z->ch[0]==y) {
if(y->ch[0]==x) {
rotate(y,1),rotate(x,1);
} else {
rotate(x,0),rotate(x,1);
}
} else {
if(y->ch[1]==x) {
rotate(y,0),rotate(x,0);
} else {
rotate(x,1),rotate(x,0);
}
}
}
}
if(f==null) {
root=x;
}
pushup(x);
}
void RotateTo(int k,Node *f) {
int tmp;
Node *t=root;
pushdown(t);
while(true) {
tmp=t->ch[0]->sz;
if(tmp + 1==k) {
break;
}
if(k<=tmp) {
t=t->ch[0];
} else {
k-=tmp + 1;
t=t->ch[1];
}
pushdown(t);
}
splay(t,f);
}
Node *build(int l,int r) {
if(l>r) {
return null;
}
int m=(l+r)>>1;
Node *p=NewNode(a[m]);
p->ch[0]=build(l,m-1);
if(p->ch[0]!=null) {
p->ch[0]->pre=p;
}
p->ch[1]=build(m+1,r);
if(p->ch[1]!=null) {
p->ch[1]->pre=p;
}
pushup(p);
return p;
}
void add(int l,int r,int v) {
RotateTo(l,null);
RotateTo(r,root);
KeyTree->add+=v;
KeyTree->val+=v;
KeyTree->Max+=v;
pushup(root->ch[1]);
pushup(root);
}
void flip(int l,int r) {
RotateTo(l,null);
RotateTo(r,root);
KeyTree->rev^=1;
}
int Max(int l,int r) {
RotateTo(l,null);
RotateTo(r,root);
return KeyTree->Max;
}
void Travel(Node *p) {
pushdown(p);
if(L!=null) {
Travel(L);
}
printf("%d ",p->val);
if(R!=null) {
Travel(R);
}
}
void debug() {
Travel(root);
puts("");
}
}spt;
inline void readT(int &ret) {
char ch, pre = 0;
while (ch = getchar(), ch < '0' || ch > '9')
pre = ch;
ret = ch ^ 0x30;
while (ch = getchar(), ch >= '0' && ch <= '9')
ret = ret*10 + (ch ^ 0x30);
if (pre == '-')
ret *= -1;
}
int main() {
int n, i, m;
//scanf("%d%d", &n, &m);
readT(n);
readT(m);
spt.init();
Node* tmp = spt.build(1, n);
spt.root->ch[1]->ch[0] = tmp;
tmp->pre = spt.root->ch[1];
spt.pushup(spt.root->ch[1]);
spt.pushup(spt.root);
//spt.debug();
for (i = 0; i < m; ++i) {
int t;
readT(t);
int l, r, v;
if (t == 1) {
readT(l);
readT(r);
readT(v);
++l, ++r;
spt.add(l - 1, r + 1, v);
}
if (t == 2) {
readT(l);
readT(r);
++l, ++r;
spt.flip(l - 1, r + 1);
}
if (t == 3) {
readT(l);
readT(r);
++l, ++r;
//spt.debug();
printf("%d\n", spt.Max(l - 1, r + 1));
}
//spt.debug();
}
return 0;
}
/*
17 11
1 8 10 2
1 6 10 -1
1 3 7 15
2 1 15
1 4 17 -2
3 5 10
2 2 10
3 3 8
2 6 10
2 1 10
3 1 10
*/