【洛谷P4146】序列终结者

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 }
AC Code
原文地址:https://www.cnblogs.com/shl-blog/p/11275930.html