Description
维护一种数据结构,并支持区间翻转、区间加、查询区间最大的操作
Solution
Splay模板题,以序列中每个元素的下标为权值建立平衡树,维护两个标记:区间翻转和区间加标记,标记下传可以仿照线段树。
剩下的就是模板了
Code
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int INF = 2147483647; 4 inline int read() { 5 int ret = 0, op = 1; 6 char c = getchar(); 7 while (!isdigit(c)) { 8 if (c == '-') op = -1; 9 c = getchar(); 10 } 11 while (isdigit(c)) { 12 ret = ret * 10 + c - '0'; 13 c = getchar(); 14 } 15 return ret * op; 16 } 17 struct Splay { 18 int sum, val, fa, ch[2], tag, rev, maxx; 19 } a[50010]; 20 int n, m, tot, root, in[50010]; 21 void update(int now) { 22 a[now].sum = a[a[now].ch[0]].sum + a[a[now].ch[1]].sum + 1; 23 a[now].maxx = max(a[now].val, max(a[a[now].ch[0]].maxx, a[a[now].ch[1]].maxx)); 24 } 25 void pushdown(int now) { 26 if (a[now].rev) { 27 a[a[now].ch[0]].rev ^= 1; 28 a[a[now].ch[1]].rev ^= 1; 29 swap(a[now].ch[0], a[now].ch[1]); 30 a[now].rev = 0; 31 } 32 if (a[now].tag) { 33 if (a[now].ch[0]) a[a[now].ch[0]].tag += a[now].tag, a[a[now].ch[0]].val += a[now].tag, a[a[now].ch[0]].maxx += a[now].tag; 34 if (a[now].ch[1]) a[a[now].ch[1]].tag += a[now].tag, a[a[now].ch[1]].val += a[now].tag, a[a[now].ch[1]].maxx += a[now].tag; 35 a[now].tag = 0; 36 } 37 } 38 void connect(int x, int fa, int op) { 39 a[x].fa = fa; 40 a[fa].ch[op] = x; 41 } 42 void rotate(int x) { 43 int y = a[x].fa; 44 int z = a[y].fa; 45 int xson = a[y].ch[1] == x ? 1 : 0; 46 int yson = a[z].ch[1] == y ? 1 : 0; 47 pushdown(x); 48 pushdown(y); 49 int B = a[x].ch[xson ^ 1]; 50 connect(B, y, xson); connect(y, x, xson ^ 1); connect(x, z, yson); 51 update(y); update(x); 52 } 53 void splay(int x, int to) { 54 while (a[x].fa != to) { 55 int y = a[x].fa; 56 int z = a[y].fa; 57 if (z != to) 58 (a[y].ch[0] == x) ^ (a[z].ch[0] == y) ? rotate(x) : rotate(y); 59 rotate(x); 60 } 61 if (to == 0) root = x; 62 } 63 int find(int x) { 64 int now = root; 65 while (now) { 66 pushdown(now); 67 if (x <= a[a[now].ch[0]].sum) now = a[now].ch[0]; 68 else { 69 x -= a[a[now].ch[0]].sum + 1; 70 if (!x) return now; 71 now = a[now].ch[1]; 72 } 73 } 74 return 0; 75 } 76 int solve(int l, int r) { 77 l = find(l); 78 r = find(r + 2); 79 splay(l, 0); splay(r, l); 80 int now = a[a[root].ch[1]].ch[0]; 81 return now; 82 } 83 int build(int fa, int l, int r) { 84 if (l > r) return 0; 85 int mid = l + r >> 1; 86 int now = ++tot; 87 a[now].maxx = a[now].val = in[mid]; 88 a[now].sum = 1; 89 a[now].fa = fa; 90 a[now].ch[0] = build(now, l, mid - 1); 91 a[now].ch[1] = build(now, mid + 1, r); 92 a[now].tag = a[now].rev = 0; 93 update(now); 94 return now; 95 } 96 int main() { 97 n = read(), m = read(); 98 a[0].maxx = -INF; 99 in[1] = -INF; in[n + 2] = -INF; 100 root = build(0, 1, n + 2); 101 while (m--) { 102 int op = read(), x = read(), y = read(), z; 103 int now = solve(x, y); 104 if (op == 1) { 105 z = read(); 106 a[now].val += z; 107 a[now].tag += z; 108 a[now].maxx += z; 109 } 110 else if (op == 2) a[now].rev ^= 1; 111 else printf("%d ", a[now].maxx); 112 } 113 return 0; 114 }