#define _CRT_SECURE_NO_WARNINGS #include<cmath> #include<iostream> #include<stdio.h> #include<algorithm> #include<map> #include<string.h> using namespace std; #define rep(i,t,n) for(int i =(t);i<=(n);++i) #define per(i,n,t) for(int i =(n);i>=(t);--i) #define mmm(a,b) memset(a,b,sizeof(a)) #define ls(n) node[n].ch[0] #define rs(n) node[n].ch[1] const int N = 100010; const int INF = 0x3f3f3f3f; struct Splay { struct Node { int fa, ch[2]; bool flip; int v, add, maxn, s; void init(int val) { v = maxn = val; s = 1; add = flip = ch[0] = ch[1] = 0; } }node[N]; int root; //维护一个结点 void pushup(int n) { node[n].maxn = max(node[n].v, max(node[ls(n)].maxn, node[rs(n)].maxn)); node[n].s = node[ls(n)].s + node[rs(n)].s + 1; } //标记向下传 void pushdown(int n) { if (n == 0) return; if (node[n].add) { if (ls(n)) { node[ls(n)].v += node[n].add; node[ls(n)].maxn += node[n].add; node[ls(n)].add += node[n].add; } if (rs(n)) { node[rs(n)].v += node[n].add; node[rs(n)].maxn += node[n].add; node[rs(n)].add += node[n].add; } node[n].add = 0; } if (node[n].flip) { if (ls(n)) node[ls(n)].flip ^= 1; if (rs(n)) node[rs(n)].flip ^= 1; swap(ls(n), rs(n)); node[n].flip = 0; } } //旋转 void rotate(int n, int d) { int fn = node[n].fa; int ffn = node[fn].fa; node[fn].ch[d ^ 1] = node[n].ch[d]; node[node[n].ch[d]].fa = fn; node[n].ch[d] = fn; node[fn].fa = n; node[ffn].ch[rs(ffn) == fn] = n; node[n].fa = ffn; pushup(fn); } //将结点n转到goal下 void splay(int n, int goal) { while (node[n].fa != goal) { int fn = node[n].fa; int ffn = node[fn].fa; pushdown(ffn), pushdown(fn), pushdown(n); bool d = (ls(fn) == n); bool d1 = (ls(ffn) == fn); if (ffn == goal) rotate(n, d); else { if (d == d1) rotate(fn, d1); else rotate(n, d); rotate(n, d1); } } pushup(n); if (goal == 0) root = n; } //找寻中序遍历中的第pos个结点 int select(int pos) { int u = root; pushdown(u); while (node[ls(u)].s != pos) { if (pos < node[ls(u)].s) u = ls(u); else { pos -= node[ls(u)].s + 1; u = rs(u); } pushdown(u); } return u; } //查询l~r最大值 int query(int l, int r) { int u = select(l - 1), v = select(r + 1); splay(u, 0); splay(v, u); return node[ls(v)].maxn; } //给l~r加上val void update(int l, int r, int val) { int u = select(l - 1), v = select(r + 1); splay(u, 0); splay(v, u); node[ls(v)].v += val; node[ls(v)].maxn += val; node[ls(v)].add += val; } //翻转l~r void reverse(int l, int r) { int u = select(l - 1), v = select(r + 1); splay(u, 0); splay(v, u); node[ls(v)].flip ^= 1; } //类似二分来建树,就是这段代码现在的我还不会用指针来替换 int build(int l, int r) { if (l > r) return 0; if (l == r) return l; int mid = (l + r) >> 1; int L, R; ls(mid) = L = build(l, mid - 1); rs(mid) = R = build(mid + 1, r); node[L].fa = node[R].fa = mid; pushup(mid); return mid; } //初始化 void init(int n) { node[0].init(-INF); node[0].s = 0; node[1].init(-INF); node[n + 2].init(-INF); for (int i = 2; i <= n + 2; i++) node[i].init(0); root = build(1, n + 2); node[root].fa = node[0].fa = 0; ls(0) = root; } }splay_tree; int main() { int n, m; scanf("%d%d", &n, &m); splay_tree.init(n); for (int i = 0; i < m; i++) { int opt, l, r, v; scanf("%d%d%d", &opt, &l, &r); if (opt == 1) { scanf("%d", &v); splay_tree.update(l, r, v); } if (opt == 2) splay_tree.reverse(l, r); if (opt == 3) printf("%d ", splay_tree.query(l, r)); } return 0; } /* const int maxn = 55; const int inf = 1e9 + 5; ll n,m; struct splay_tree { struct node { int val, mx, add, sz, son[2]; bool rev; void init(int _val) { val = mx = _val, sz = 1, add = rev = son[0] = son[1]; } }T[maxn]; int fa[maxn], root; void Rotate(int x, int kind) { 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;//orz } void Splay(int x,) }; string s[maxn]; map<char, int> mmp; int main() { cin >> n >> m; hehe.init(); for (int i = 0, a, b, c, d; i < m; i++) { scanf("%d", &a); if (a == 1) { scanf("%d%d%d", &b, &c, &d); hehe.update(b, c, d); } else if (a == 2) { scanf("%d%d", &b, &c); hehe.Reverse(b, c); } else { scanf("%d%d", &b, &c); printf("%d "); hehe.query(b, c); } } return 0; }*/