Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <map>
- #include <vector>
- #include <algorithm>
- #include <string>
- using namespace std;
- struct node {
- node *left, *right;
- int size;
- int value;
- int priority;
- int sum;
- int promise;
- int reverse;
- node (int value = 0):
- left(nullptr),
- right(nullptr),
- size(1),
- value(value),
- priority((rand() << 16) | rand()),
- sum(value),
- promise(0),
- reverse(0)
- {}
- };
- int sum(node *v) {
- if (v == nullptr) {
- return 0;
- } else {
- return v->sum;
- }
- }
- int size(node *v) {
- if (v == nullptr) {
- return 0;
- } else {
- return v->size;
- }
- }
- void down(node *v, int promise, int r) {
- if (v == nullptr) {
- return;
- } else {
- v->promise += promise;
- v->reverse ^= r;
- }
- }
- void push(node *v) {
- if (v == nullptr) {
- return;
- }
- v->sum += v->promise * v->size;
- v->value += v->promise;
- if (v->reverse) {
- swap(v->left, v->right);
- }
- down(v->left, v->promise, v->reverse);
- down(v->right, v->promise, v->reverse);
- v->promise = 0;
- v->reverse = 0;
- }
- void up(node *v) {
- push(v->left);
- push(v->right);
- v->size = size(v->left) + size(v->right) + 1;
- v->sum = sum(v->left) + sum(v->right) + v->value;
- }
- node *merge(node *root_l, node *root_r) {
- push(root_l);
- push(root_r);
- if (root_l == nullptr) {
- return root_r;
- }
- if (root_r == nullptr) {
- return root_l;
- }
- if (root_l->priority < root_r->priority) {
- root_l->right = merge(root_l->right, root_r);
- up(root_l);
- return root_l;
- } else {
- root_r->left = merge(root_l, root_r->left);
- up(root_r);
- return root_r;
- }
- }
- pair <node*, node*> split(node *root, int cnt) {
- if (root == nullptr) {
- return {nullptr, nullptr};
- }
- push(root);
- if (size(root->left) >= cnt) {
- auto p = split(root->left, cnt);
- root->left = p.second;
- up(root);
- return {p.first, root};
- } else {
- auto p = split(root->right, cnt - size(root->left) - 1);
- root->right = p.first;
- up(root);
- return {root, p.second};
- }
- }
- void write(node *root) {
- if (root == nullptr) {
- return;
- }
- push(root);
- write(root->left);
- cout << root->value << " ";
- write(root->right);
- }
- void write(node *root, int cnt) {
- if (root == nullptr) {
- return;
- }
- write(root->left, cnt + 1);
- for (int i = 0; i < cnt; ++i) {
- cout << " ";
- }
- cout << root->value << " " << root->reverse << endl;
- write(root->right, cnt + 1);
- }
- node *root = nullptr;
- int sum(int l, int r) {
- auto p1 = split(root, r + 1);
- auto p2 = split(p1.first, l);
- int ans = sum(p2.second);
- root = merge(p2.first, merge(p2.second, p1.second));
- return ans;
- }
- void upd(int l, int r, int k) {
- auto p1 = split(root, r + 1);
- auto p2 = split(p1.first, l);
- down(p2.second, k, 0);
- root = merge(p2.first, merge(p2.second, p1.second));
- }
- void reverse(int l, int r) {
- auto p1 = split(root, r + 1);
- auto p2 = split(p1.first, l);
- down(p2.second, 0, 1);
- root = merge(p2.first, merge(p2.second, p1.second));
- }
- int main() {
- int n, m;
- cin >> n >> m;
- for (int i = 0; i < n; ++i) {
- int a;
- cin >> a;
- root = merge(root, new node(a));
- }
- for (int i = 0; i < m; ++i) {
- char t;
- cin >> t;
- if (t == '?') {
- int l, r;
- cin >> l >> r;
- --l;
- --r;
- cout << sum(l, r) << endl;
- cout << endl;
- write(root, 0);
- cout << endl;
- }
- if (t == '+') {
- int l, r, k;
- cin >> l >> r >> k;
- upd(l - 1, r - 1, k);
- }
- if (t == 'w') {
- write(root);
- cout << endl;
- }
- if (t == 'r') {
- int l, r;
- cin >> l >> r;
- reverse(l - 1, r - 1);
- write(root, 0);
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement