#include <cstdio> #include <cstdlib> #include <cstring> #include <climits> #include <stack> #include <algorithm> const int N = 500000; int n, m; int a[N + 1]; struct Data { int sum, lsum, rsum, maxSum; Data(int x = INT_MIN) : sum(x), lsum(x), rsum(x), maxSum(x) {} static Data merge(const Data &l, const Data &r) { Data res; res.sum = l.sum + r.sum; res.lsum = res.sum; res.lsum = std::max(res.lsum, l.lsum); res.lsum = std::max(res.lsum, l.sum + r.lsum); res.rsum = res.sum; res.rsum = std::max(res.rsum, r.rsum); res.rsum = std::max(res.rsum, l.rsum + r.sum); res.maxSum = res.sum; res.maxSum = std::max(res.maxSum, l.maxSum); res.maxSum = std::max(res.maxSum, r.maxSum); res.maxSum = std::max(res.maxSum, l.rsum + r.lsum); return res; } static Data merge(const Data &l, int x, const Data &r) { Data v(x); if (l.sum == INT_MIN && r.sum == INT_MIN) return v; if (l.sum == INT_MIN) { if (x == INT_MIN) return r; else return merge(v, r); } else if (r.sum == INT_MIN) { if (x == INT_MIN) return l; else return merge(l, v); } else { if (x == INT_MIN) return merge(l, r); else return merge(merge(l, v), r); } } }; struct Treap { struct Node { Node *lc, *rc; int key; int x, size; Data data; int tag; bool rev; Node (int x = INT_MIN) : lc(NULL), rc(NULL), key(rand()), x(x), size(1), data(), tag(INT_MAX), rev(false) {} ~Node() { if (lc) delete lc; if (rc) delete rc; } void cover(int val) { x = val; int s = size * x; data = Data(std::max(s, x)); data.sum = s; tag = x; } void reverse() { std::swap(data.lsum, data.rsum); rev ^= 1; } void pushDown() { if (tag != INT_MAX) { if (lc) lc->cover(tag); if (rc) rc->cover(tag); tag = INT_MAX; } if (rev) { std::swap(lc, rc); if (lc) lc->reverse(); if (rc) rc->reverse(); rev = false; } } void update() { size = (lc ? lc->size : 0) + (rc ? rc->size : 0) + 1; Data ld = INT_MIN, rd = INT_MIN; if (lc) ld = lc->data; if (rc) rd = rc->data; data = Data::merge(ld, x, rd); } int lsize() { return lc ? lc->size : 0; } void print() { printf("%d -> sum = %d, maxSum = %d, lMaxSum = %d, rMaxSum = %d\n", x, data.sum, data.maxSum, data.lsum, data.rsum); } } *root; Treap() : root(NULL) { srand(20000704 ^ 20000116); } Node *merge(Node *a, Node *b) { if (!a) return b; if (!b) return a; if (a->key > b->key) { a->pushDown(); a->rc = merge(a->rc, b); a->update(); return a; } else { b->pushDown(); b->lc = merge(a, b->lc); b->update(); return b; } } void split(Node *v, int k, Node *&l, Node *&r) { if (!v) { l = r = NULL; return; } v->pushDown(); int s = v->lsize(); if (k <= s) { split(v->lc, k, l, r); v->lc = r; r = v; } else { split(v->rc, k - s - 1, l, r); v->rc = l; l = v; } v->update(); } void insert(int p, int c) { if (p == 0) { root = merge(build(c), root); return; } Node *pred, *succ; split(root, p, pred, succ); root = merge(merge(pred, build(c)), succ); } Node *build(int n) { std::stack<Node *> s; while (!s.empty()) s.pop(); Node *v, *last; for (int i = 1; i <= n; i++) { v = new Node(a[i]); last = NULL; while (!s.empty() && v->key > s.top()->key) { last = s.top(); s.pop(); last->update(); } if (!s.empty()) s.top()->rc = v; v->lc = last; s.push(v); } while (s.size() != 1) { s.top()->update(); s.pop(); } Node *res = s.top(); s.pop(); res->update(); return res; } void del(int p, int c) { int l = p, r = p + c - 1; Node *pred, *succ, *mid, *tar; split(root, l - 1, pred, tar); split(tar, r - l + 1, mid, succ); delete mid; root = merge(pred, succ); } void change(int p, int c, int x) { int l = p, r = p + c - 1; Node *pred, *succ, *mid, *tar; split(root, l - 1, pred, tar); split(tar, r - l + 1, mid, succ); mid->cover(x); root = merge(merge(pred, mid), succ); } void reverse(int p, int c) { int l = p, r = p + c - 1; Node *pred, *succ, *mid, *tar; split(root, l - 1, pred, tar); split(tar, r - l + 1, mid, succ); mid->reverse(); root = merge(merge(pred, mid), succ); } int sum(int p, int c) { int l = p, r = p + c - 1, res; Node *pred, *succ, *mid, *tar; split(root, l - 1, pred, tar); split(tar, r - l + 1, mid, succ); res = mid->data.sum; #ifdef DBG #endif root = merge(merge(pred, mid), succ); return res; } int maxSum() { return root->data.maxSum; } void print(Node *v, int dep = 0) { if (!v) return; v->pushDown(); print(v->lc, dep + 1); v->print(); print(v->rc, dep + 1); } } treap; int main() { scanf("%d %d", &n, &m); for (int i = 1; i <= n; i++) scanf("%d", &a[i]); treap.root = treap.build(n); #ifdef DBG #endif char cmd[sizeof("MAKE-SAME")]; for (int T = 1; T <= m; T++) { scanf("%s", cmd); if (cmd[2] == 'X') printf("%d\n", treap.maxSum()); else { int p, c; scanf("%d %d", &p, &c); if (cmd[2] == 'S') { for (int i = 1; i <= c; i++) scanf("%d", &a[i]); treap.insert(p, c); } else if (cmd[2] == 'L') { treap.del(p, c); } else if (cmd[2] == 'K') { int x; scanf("%d", &x); treap.change(p, c, x); } else if (cmd[2] == 'V') { treap.reverse(p, c); } else if (cmd[2] == 'T') { if (c == 0) puts("0"); else printf("%d\n", treap.sum(p, c)); } } } return 0; }
|