Advertisement
KShah

Untitled

Jan 24th, 2022
1,421
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.85 KB | None | 0 0
  1. //
  2. //  main.cpp
  3. //  SplayTree
  4. //
  5. //  Created by kshakh on 14.12.2021.
  6. //
  7. #include <cassert>
  8. #include <climits>
  9. #include <cstring>
  10. #include <iostream>
  11. #include <vector>
  12.  
  13. using std::cin;
  14. using std::cout;
  15. using std::vector;
  16. using std::string;
  17. using std::max;
  18. using std::min;
  19.  
  20. struct Node {
  21.     long long sum;
  22.     long long key = -1; // all numbers not less than 0
  23.     Node* left = nullptr;
  24.     Node* right = nullptr;
  25.     Node* parent = nullptr;
  26.    
  27.     Node(Node* par, long long val) : key(val), parent(par) {}
  28.     void UpdateSum() {
  29.         sum = key + (left != nullptr ? left->sum : 0) +
  30.                 (right != nullptr ? right->sum : 0);
  31.     }
  32. };
  33.  
  34. class SplayTree {
  35. public:
  36.     SplayTree() : root(nullptr) {}
  37.     ~SplayTree() {
  38.         DeleteRoots(root);
  39.     }
  40.     void Add(long long val);
  41.     long long Sum(long long l, long long r);
  42. private:
  43.     Node* root;
  44.    
  45.     void DeleteRoots(Node* p) {
  46.         if (p == nullptr) return;
  47.         DeleteRoots(p->left);
  48.         DeleteRoots(p->right);
  49.         delete p;
  50.     }
  51.    
  52.     void zig(Node* son, Node* par) {
  53.         par->left = son->right;
  54.         if (par->left != nullptr) {
  55.             par->left->parent = par;
  56.         }
  57.         son->right = par;
  58.         son->parent = par->parent;
  59.         par->parent = son;
  60.        
  61.         // update parent's parent son information
  62.         if (son->parent != nullptr) {
  63.             if (son->parent->left == par) {
  64.                 son->parent->left = son;
  65.             } else {
  66.                 son->parent->right = son;
  67.             }
  68.         }
  69.        
  70.         par->UpdateSum();
  71.         son->UpdateSum();
  72.     }
  73.    
  74.     void zag(Node* son, Node* par) {
  75.         par->right = son->left;
  76.         if (par->right != nullptr) {
  77.             par->right->parent = par;
  78.         }
  79.         son->left = par;
  80.         son->parent = par->parent;
  81.         par->parent = son;
  82.        
  83.         // update parent's parent son information
  84.         if (son->parent != nullptr) {
  85.             if (son->parent->left == par) {
  86.                 son->parent->left = son;
  87.             } else {
  88.                 son->parent->right = son;
  89.             }
  90.         }
  91.        
  92.         par->UpdateSum();
  93.         son->UpdateSum();
  94.     }
  95.    
  96.     void Splay(Node* p);
  97.     Node* Find(Node* p, long long val);
  98.     void Insert(Node* p, long long val);
  99.     Node* Merge(Node* left, Node* right);
  100.     std::pair<Node*, Node*> Split(Node* p, long long val);
  101. };
  102.  
  103. void SplayTree::Splay(Node* p) {
  104.     if (p == nullptr) return;
  105.     if (p->parent == nullptr) root = p;
  106.     else {
  107.         Node* par = p->parent;
  108.         Node* grandpar = par->parent;
  109.         // zig or zag, if grandparent is nullptr
  110.         if (grandpar == nullptr) {
  111.             if (par->left == p) {
  112.                 zig(p, par);
  113.             } else {
  114.                 zag(p, par);
  115.             }
  116.         } else {
  117.             // zig/zag-zag/zig
  118.             if (par->left == p && grandpar->left == par) { // zig-zig
  119.                 zig(par, grandpar);
  120.                 zig(p, par);
  121.             } else if (par->right == p && grandpar->left == par) { // zag-zig
  122.                 zag(p, par);
  123.                 zig(p, grandpar);
  124.             } else if (par->left == p && grandpar->right == par) { // zig-zag
  125.                 zig(p, par);
  126.                 zag(p, grandpar);
  127.             } else { // zag-zag
  128.                 zag(par, grandpar);
  129.                 zag(p, par);
  130.             }
  131.         }
  132.         Splay(p);
  133.     }
  134. }
  135.  
  136. Node* SplayTree::Find(Node* p, long long val) {
  137.     if (p == nullptr || p->key == val) return p;
  138.    
  139.     // find the pos in subtree
  140.     Node* res = nullptr;
  141.     if (p->key > val) {
  142.         res = Find(p->left, val);
  143.     } else {
  144.         res = Find(p->right, val);
  145.     }
  146.    
  147.     if (res == nullptr || (res->key < val && val < p->key)) {
  148.         res = p;
  149.     }
  150.  
  151.     return res;
  152. }
  153.  
  154. void SplayTree::Add(long long val) {
  155.     Node* res = Find(root, val);
  156.     if (res == nullptr || res->key != val) {
  157.         Insert(root, val);
  158.     } else {
  159.         Splay(res);
  160.     }
  161. }
  162.  
  163. void SplayTree::Insert(Node* p, long long val) {
  164.     if (p == nullptr) {
  165.         root = new Node(nullptr, val);
  166.         return;
  167.     }
  168.     if (p->key > val) {
  169.         if (p->left == nullptr) {
  170.             p->left = new Node(p, val);
  171.             Splay(p->left);
  172.         } else {
  173.             Insert(p->left, val);
  174.         }
  175.     } else {
  176.         if (p->right == nullptr) {
  177.             p->right = new Node(p, val);
  178.             Splay(p->right);
  179.         } else {
  180.             Insert(p->right, val);
  181.         }
  182.     }
  183. }
  184.  
  185. Node* SplayTree::Merge(Node *left, Node *right) {
  186.     if (left == nullptr && right == nullptr) {
  187.         return nullptr;
  188.     } else if (left == nullptr) {
  189.         right->parent = nullptr;
  190.         return right;
  191.     } else if (right == nullptr) {
  192.         left->parent = nullptr;
  193.         return left;
  194.     }
  195.    
  196.     Node* Maxi = left;
  197.     while (Maxi->right != nullptr) {
  198.         Maxi = Maxi->right;
  199.     }
  200.     Splay(Maxi);
  201.     Maxi->right = right;
  202.     right->parent = Maxi;
  203.     Maxi->parent = nullptr;
  204.     Maxi->UpdateSum();
  205.     return Maxi;
  206. }
  207.  
  208. std::pair<Node*, Node*> SplayTree::Split(Node* p, long long val) {
  209.     Node* node = Find(p, val);
  210.     Splay(node);
  211.     if (node == nullptr) {
  212.         return { nullptr, nullptr };
  213.     }
  214.    
  215.     if (node->key < val) {
  216.         return { node, nullptr };
  217.     } else {
  218.         if (node->left != nullptr) {
  219.             node->left->parent = nullptr;
  220.         }
  221.         Node* less = node->left;
  222.         node->left = nullptr;
  223.         node->UpdateSum();
  224.         return { less, node };
  225.     }
  226. }
  227.  
  228. long long SplayTree::Sum(long long l, long long r) {
  229.     std::pair<Node*, Node*> less = Split(root, l);
  230.     if (less.second == nullptr) {
  231.         root = less.first;
  232.         return 0LL;
  233.     }
  234.     std::pair<Node*, Node*> great = Split(less.second, r + 1);
  235.     if (great.first == nullptr) {
  236.         root = Merge(less.first, great.second);
  237.         return 0;
  238.     } else {
  239.         long long res = great.first->sum;
  240.         root = Merge(less.first, Merge(great.first, great.second));
  241.         return res;
  242.     }
  243. }
  244.  
  245.  
  246. int main() {
  247.     int n;
  248.     std::cin >> n;
  249.     SplayTree tree;
  250.    
  251.     long long MOD = 1000000000;
  252.    
  253.     char sign, prev = '+';
  254.     long long prevRes;
  255.     long long numb;
  256.     long long left_, right_;
  257.    
  258.     for (int i = 0; i < n; ++i) {
  259.         cin >> sign;
  260.         if (sign == '+') {
  261.             cin >> numb;
  262.             if (prev == '+') {
  263.                 tree.Add(numb);
  264.             } else {
  265.                 long long tmp = (prevRes % MOD + numb) % MOD;
  266.                 tree.Add(tmp);
  267.             }
  268.             prev = '+';
  269.         } else {
  270.             prev = '?';
  271.             cin >> left_ >> right_;
  272.             prevRes = tree.Sum(left_, right_);
  273.             cout << prevRes << "\n";
  274.         }
  275.     }
  276.    
  277.     return 0;
  278. }
  279.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement