【解析】
平衡树神仙题,debug 5h+。
思路到很简单,直接打标记维护。
FHQ Treap 要加上 O(n)建树才能 AC。
【代码】
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int inf = 1 << 30;
const int maxn = 5e5 + 10;
int n, m, a[maxn], c[maxn];
int s[maxn], top;
inline int randn() {
static int seed = 131;
seed *= 13331;
return seed;
}
inline int max(int a, int b, int c) { return max(a, max(b, c)); }
inline int max(int a, int b, int c, int d, int e) { return max(max(a, b), c, max(d, e)); }
// Treap
struct node {
int val, sum; // 权值,区间和
int sub, pre, suf; // 最大子段和、前缀和、后缀和
int ass, rev; // 赋值、翻转标记
int fix, size; // 维护值,子树大小
int lc, rc; // 左右子树
} t[maxn];
int rec[maxn], r, cnt, root;
inline int new_node(int val) { // 创建新结点
static int x;
if (r) x = rec[r--];
else x = ++cnt;
t[x] = (node){ val, val, val, max(val, 0), max(val, 0), inf, 0, randn(), 1, 0, 0 };
return x;
}
inline void push_up(int o) { // 标记上推
static int lc, rc;
if (!o) return;
lc = t[o].lc, rc = t[o].rc;
t[o].sum = t[lc].sum + t[o].val + t[rc].sum;
t[o].sub = max(t[o].val, t[lc].suf + t[o].val + t[rc].pre);
if (lc) t[o].sub = max(t[o].sub, t[lc].sub);
if (rc) t[o].sub = max(t[o].sub, t[rc].sub);
t[o].pre = max(t[lc].pre, t[lc].sum + t[o].val + t[rc].pre, 0);
t[o].suf = max(t[lc].suf + t[o].val + t[rc].sum, t[rc].suf, 0);
t[o].size = t[lc].size + 1 + t[rc].size;
}
inline void tag(int o, int x) { // 区间赋值
t[o].val = x;
t[o].sum = x * t[o].size;
t[o].pre = t[o].suf = max(t[o].sum, 0);
t[o].sub = max(t[o].sum, x);
t[o].ass = x;
}
inline void reve(int o) {
swap(t[o].pre, t[o].suf);
swap(t[o].lc, t[o].rc);
t[o].rev ^= 1;
}
inline void push_down(int o) { // 标记下推
static int lc, rc, x;
if (!o) return;
lc = t[o].lc, rc = t[o].rc;
if (t[o].rev) {
if (lc) reve(lc);
if (rc) reve(rc);
t[o].rev ^= 1;
}
if (t[o].ass != inf) {
x = t[o].ass;
if (lc) tag(lc, x);
if (rc) tag(rc, x);
t[o].ass = inf;
}
}
int build(int *a, int k) { // 建树
static int root, x, y;
memset(s, 0, sizeof s);
for (int i = 1; i <= k; ++i) {
x = new_node(a[i]), y = 0;
while (top && t[x].fix < t[s[top]].fix) { y = s[top--]; push_up(y); }
s[++top] = x;
t[x].lc = y;
if (top) t[s[top - 1]].rc = x;
if (top == 1) root = x;
}
while (top) push_up(s[top--]);
return root;
}
void split(int o, int k, int &x, int &y) {
if (!o) { x = y = 0; return; }
push_down(o);
if (t[t[o].lc].size < k) {
x = o;
split(t[o].rc, k - t[t[o].lc].size - 1, t[o].rc, y);
} else {
y = o;
split(t[o].lc, k, x, t[o].lc);
}
push_up(o);
}
int merge(int x, int y) {
if (!x || !y) return x + y;
if(t[x].fix < t[y].fix) {
push_down(x);
t[x].rc = merge(t[x].rc, y);
push_up(x);
return x;
} else {
push_down(y);
t[y].lc = merge(x, t[y].lc);
push_up(y);
return y;
}
}
int merge(int u, int v, int w) { return merge(u, merge(v, w)); }
/*
int build(int *a, int k) {
if (k == 0) return 0;
int root = 0;
for (int i = 1; i <= k; i++) root = merge(root, new_node(a[i]));
return root;
}
*/
void recycle(int o) { // 回收树
rec[++r] = o;
if (t[o].lc) recycle(t[o].lc);
if (t[o].rc) recycle(t[o].rc);
}
void travel(int o) {
if (t[o].lc) travel(t[o].lc);
cout << t[o].val << " ";
if (t[o].rc) travel(t[o].rc);
}
inline void read(int& x) {
static char c;
static bool f;
x = 0, f = true, c = getchar();
while (!isdigit(c)) { if (c == '-') f = false; c = getchar(); }
while (isdigit(c)) { x = (x << 1) + (x << 3) + (c ^ 48); c = getchar(); }
if (!f) x = -x;
}
int main() {
read(n), read(m);
for (int i = 1; i <= n; ++i) read(a[i]);
root = build(a, n);
char op[10];
int pos, tot, u, v, w, x, ans;
while (m--) {
scanf("%s", op + 1);
if (op[1] == 'I') { // INSERT
read(pos), read(tot);
for (int i = 1; i <= tot; ++i) read(c[i]);
split(root, pos, u, w);
v = build(c, tot);
root = merge(u, v, w);
} else if (op[1] == 'D') { // DELETE
read(pos), read(tot);
split(root, pos - 1, u, v);
split(v, tot, v, w);
root = merge(u, w);
recycle(v);
} else if (op[1] == 'M' && op[3] == 'K') { // MAKE SAME
read(pos), read(tot), read(x);
split(root, pos - 1, u, v);
split(v, tot, v, w);
tag(v, x);
root = merge(u, v, w);
} else if (op[1] == 'R') { // REVERSE
read(pos), read(tot);
split(root, pos - 1, u, v);
split(v, tot, v, w);
reve(v);
root = merge(u, v, w);
} else if (op[1] == 'G') { // GET SUM
read(pos), read(tot);
split(root, pos - 1, u, v);
split(v, tot, v, w);
ans = t[v].sum;
printf("%d\n", ans);
root = merge(u, v, w);
} else { // MAX SUM
ans = t[root].sub;
printf("%d\n", ans);
}
}
return 0;
}