Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //
- // main.cpp
- // SplayTree
- //
- // Created by kshakh on 14.12.2021.
- //
- #include <cassert>
- #include <climits>
- #include <cstring>
- #include <iostream>
- #include <vector>
- using std::cin;
- using std::cout;
- using std::vector;
- using std::string;
- using std::max;
- using std::min;
- struct Node {
- long long sum;
- long long key = -1; // all numbers not less than 0
- Node* left = nullptr;
- Node* right = nullptr;
- Node* parent = nullptr;
- Node(Node* par, long long val) : key(val), parent(par) {}
- void UpdateSum() {
- sum = key + (left != nullptr ? left->sum : 0) +
- (right != nullptr ? right->sum : 0);
- }
- };
- class SplayTree {
- public:
- SplayTree() : root(nullptr) {}
- ~SplayTree() {
- DeleteRoots(root);
- }
- void Add(long long val);
- long long Sum(long long l, long long r);
- private:
- Node* root;
- void DeleteRoots(Node* p) {
- if (p == nullptr) return;
- DeleteRoots(p->left);
- DeleteRoots(p->right);
- delete p;
- }
- void zig(Node* son, Node* par) {
- par->left = son->right;
- if (par->left != nullptr) {
- par->left->parent = par;
- }
- son->right = par;
- son->parent = par->parent;
- par->parent = son;
- // update parent's parent son information
- if (son->parent != nullptr) {
- if (son->parent->left == par) {
- son->parent->left = son;
- } else {
- son->parent->right = son;
- }
- }
- par->UpdateSum();
- son->UpdateSum();
- }
- void zag(Node* son, Node* par) {
- par->right = son->left;
- if (par->right != nullptr) {
- par->right->parent = par;
- }
- son->left = par;
- son->parent = par->parent;
- par->parent = son;
- // update parent's parent son information
- if (son->parent != nullptr) {
- if (son->parent->left == par) {
- son->parent->left = son;
- } else {
- son->parent->right = son;
- }
- }
- par->UpdateSum();
- son->UpdateSum();
- }
- void Splay(Node* p);
- Node* Find(Node* p, long long val);
- void Insert(Node* p, long long val);
- Node* Merge(Node* left, Node* right);
- std::pair<Node*, Node*> Split(Node* p, long long val);
- };
- void SplayTree::Splay(Node* p) {
- if (p == nullptr) return;
- if (p->parent == nullptr) root = p;
- else {
- Node* par = p->parent;
- Node* grandpar = par->parent;
- // zig or zag, if grandparent is nullptr
- if (grandpar == nullptr) {
- if (par->left == p) {
- zig(p, par);
- } else {
- zag(p, par);
- }
- } else {
- // zig/zag-zag/zig
- if (par->left == p && grandpar->left == par) { // zig-zig
- zig(par, grandpar);
- zig(p, par);
- } else if (par->right == p && grandpar->left == par) { // zag-zig
- zag(p, par);
- zig(p, grandpar);
- } else if (par->left == p && grandpar->right == par) { // zig-zag
- zig(p, par);
- zag(p, grandpar);
- } else { // zag-zag
- zag(par, grandpar);
- zag(p, par);
- }
- }
- Splay(p);
- }
- }
- Node* SplayTree::Find(Node* p, long long val) {
- if (p == nullptr || p->key == val) return p;
- // find the pos in subtree
- Node* res = nullptr;
- if (p->key > val) {
- res = Find(p->left, val);
- } else {
- res = Find(p->right, val);
- }
- if (res == nullptr || (res->key < val && val < p->key)) {
- res = p;
- }
- return res;
- }
- void SplayTree::Add(long long val) {
- Node* res = Find(root, val);
- if (res == nullptr || res->key != val) {
- Insert(root, val);
- } else {
- Splay(res);
- }
- }
- void SplayTree::Insert(Node* p, long long val) {
- if (p == nullptr) {
- root = new Node(nullptr, val);
- return;
- }
- if (p->key > val) {
- if (p->left == nullptr) {
- p->left = new Node(p, val);
- Splay(p->left);
- } else {
- Insert(p->left, val);
- }
- } else {
- if (p->right == nullptr) {
- p->right = new Node(p, val);
- Splay(p->right);
- } else {
- Insert(p->right, val);
- }
- }
- }
- Node* SplayTree::Merge(Node *left, Node *right) {
- if (left == nullptr && right == nullptr) {
- return nullptr;
- } else if (left == nullptr) {
- right->parent = nullptr;
- return right;
- } else if (right == nullptr) {
- left->parent = nullptr;
- return left;
- }
- Node* Maxi = left;
- while (Maxi->right != nullptr) {
- Maxi = Maxi->right;
- }
- Splay(Maxi);
- Maxi->right = right;
- right->parent = Maxi;
- Maxi->parent = nullptr;
- Maxi->UpdateSum();
- return Maxi;
- }
- std::pair<Node*, Node*> SplayTree::Split(Node* p, long long val) {
- Node* node = Find(p, val);
- Splay(node);
- if (node == nullptr) {
- return { nullptr, nullptr };
- }
- if (node->key < val) {
- return { node, nullptr };
- } else {
- if (node->left != nullptr) {
- node->left->parent = nullptr;
- }
- Node* less = node->left;
- node->left = nullptr;
- node->UpdateSum();
- return { less, node };
- }
- }
- long long SplayTree::Sum(long long l, long long r) {
- std::pair<Node*, Node*> less = Split(root, l);
- if (less.second == nullptr) {
- root = less.first;
- return 0LL;
- }
- std::pair<Node*, Node*> great = Split(less.second, r + 1);
- if (great.first == nullptr) {
- root = Merge(less.first, great.second);
- return 0;
- } else {
- long long res = great.first->sum;
- root = Merge(less.first, Merge(great.first, great.second));
- return res;
- }
- }
- int main() {
- int n;
- std::cin >> n;
- SplayTree tree;
- long long MOD = 1000000000;
- char sign, prev = '+';
- long long prevRes;
- long long numb;
- long long left_, right_;
- for (int i = 0; i < n; ++i) {
- cin >> sign;
- if (sign == '+') {
- cin >> numb;
- if (prev == '+') {
- tree.Add(numb);
- } else {
- long long tmp = (prevRes % MOD + numb) % MOD;
- tree.Add(tmp);
- }
- prev = '+';
- } else {
- prev = '?';
- cin >> left_ >> right_;
- prevRes = tree.Sum(left_, right_);
- cout << prevRes << "\n";
- }
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement