Treap 是坠吼的啊!!!!!!!

Description

Description

Solution

前五个是 Simple 的平衡树操作。 最后一个需要一点小技巧,详见代码。

还有就是不要忘记把删掉的节点delete掉。

在这道题之后我加入 Treap 神教了!

Code

#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;
}
// divide
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;
// Val reserved
int key;
int x, size;
Data data;
// tags
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() {
// reload size
size = (lc ? lc->size : 0) + (rc ? rc->size : 0) + 1;
// divide the array into 3 parts
// merge them one by one
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);
}
// a < b
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() {
// print(root);
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
// treap.print(treap.root);
#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;
}