Advertisement
Guest User

Untitled

a guest
Apr 19th, 2019
104
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.77 KB | None | 0 0
  1. #include <iostream>
  2. #include <cmath>
  3. #include <math.h>
  4. #include <random>
  5.  
  6. using namespace std;
  7.  
  8. struct Node {
  9.     long long x, y;
  10.     long long sum = 0;
  11.     Node *left, *right;
  12. }; //+
  13.  
  14. Node * root = nullptr;
  15. long long n, x, y;
  16. char c;
  17. long long result = 0;
  18. long long a[20000000];
  19.  
  20. //написать все связанное с суммой
  21. void rangeCalc(Node *node) {
  22.     if (node == nullptr)
  23.         return;
  24.     long long w = node->right == nullptr ? 0 : node->right->sum;
  25.     w += node->left == nullptr ? 0 : node->left->sum;
  26.     node->sum = w + node->x;
  27. } //+
  28.  
  29. bool contains(Node *node, long long e) {
  30.     if (node == nullptr)
  31.         return false;
  32.     if (e == node->x)
  33.         return true;
  34.     if (e > node->x) {
  35.         return contains(node->right, e);
  36.     }
  37.     else {
  38.         return contains(node->left, e);
  39.     }
  40.     //to->y = node->y;
  41. } //+
  42.  
  43. Node * next(Node *node, long long e) {
  44.     Node * current = node, *successor = nullptr;
  45.     while (current != nullptr) {
  46.         if (current->x > e) {
  47.             successor = current;
  48.             current = current->left;
  49.         } else
  50.             current = current->right;
  51.     }
  52.     if (successor == nullptr) {
  53.         Node *to = new Node();
  54.         to->x = INT64_MIN;
  55.         return to;
  56.     }
  57.     return successor;
  58. }
  59.  
  60. Node * prev(Node *node, long long e) {
  61.     Node * current = node, *predecessor = nullptr;
  62.     while (current != nullptr) {
  63.         if (current->x < e) {
  64.             predecessor = current;
  65.             current = current->right;
  66.         } else
  67.             current = current->left;
  68.     }
  69.     if (predecessor == nullptr) {
  70.         Node *to = new Node();
  71.         to->x = INT64_MAX;
  72.         return to;
  73.     }
  74.     return predecessor;
  75. } //+
  76.  
  77. Node * merge(Node *A, Node* B) {
  78.     if (A == nullptr) {
  79.         rangeCalc(A);
  80.         rangeCalc(B);
  81.         return B;
  82.     } //+
  83.     if (B == nullptr) {
  84.         rangeCalc(A);
  85.         rangeCalc(B);
  86.         return A;
  87.     } //+
  88.     if (A->y < B->y) {
  89.         A->right = merge(A->right, B);
  90.         rangeCalc(B);
  91.         rangeCalc(A);
  92.         return A;
  93.     } //+
  94.     else {
  95.         B->left = merge(A, B->left);
  96.         rangeCalc(A);
  97.         rangeCalc(B);
  98.         return B;
  99.     } //+
  100. }
  101.  
  102. pair<Node *, Node *> split(Node *A, long long e) {
  103.     if (A == nullptr) {
  104.         return make_pair(nullptr, nullptr);
  105.     }
  106.     /*if (A->x == x) {
  107.         Node * res1 = merge(A, A->right);
  108.         rangeCalc(res1);
  109.         pair<Node *, Node *> res = make_pair(A->left, res1);
  110.         rangeCalc(A);
  111.         return  make_pair(res.first, res.second);
  112.     }*/
  113.     /*if (A->x == e) {
  114.         Node * res1 = merge(A->left, A);
  115.         rangeCalc(res1);
  116.         pair<Node *, Node *> res = make_pair(res1, A->right);
  117.         rangeCalc(A);
  118.         return  make_pair(res.first, res.second);
  119.     }*/
  120.     if (A->x < e) {
  121.         pair<Node *, Node *> res = split(A->right, e);
  122.         //rangeCalc(res.second);
  123.         A->right = res.first;
  124.         rangeCalc(A);
  125.         rangeCalc(res.first);
  126.         return make_pair(A, res.second);
  127.     }
  128.     else {
  129.         pair<Node *, Node *> res = split(A->left, e);
  130.         //rangeCalc(res.first);
  131.         A->left = res.second;
  132.         rangeCalc(A);
  133.         rangeCalc(res.second);
  134.         return make_pair(res.first, A);
  135.     }
  136. }
  137.  
  138. Node * insert(Node * A, Node * nd) {
  139.     rangeCalc(A);
  140.     pair<Node *, Node *> res = split(A, nd->x + 1);
  141.     rangeCalc(res.first);
  142.     rangeCalc(res.second);
  143.     Node * T = merge(res.first, nd);
  144.     rangeCalc(T);
  145.     rangeCalc(res.second);
  146.     A = merge(T, res.second);
  147.     rangeCalc(A);
  148.     return A;
  149. }
  150.  
  151. /*pair<Node *, long long> sum(Node *node, long long l, long long r) { //[l, r)
  152.     long long leftSum = 0;
  153.     long long rightSum = 0;
  154.     long long nodeRes = 0;
  155.     if (node == nullptr) {
  156.         return make_pair(node, 0);
  157.     }
  158.     if (node->x >= l && node->x < r) { //+
  159.         nodeRes = node->x;
  160.     }
  161.     if (node->leftBound >= r || node->rightBound <= l) { //+
  162.         rangeCalc(node);
  163.         return make_pair(node, 0);
  164.     }
  165.     if (node->leftBound >= l && node->rightBound <= r) {
  166.         rangeCalc(node);
  167.         long long w = node->right == nullptr ? 0 : node->right->sum;
  168.         w += node->left == nullptr ? 0 : node->left->sum;
  169.         node->sum = w + node->x;
  170.         return make_pair(node, w + node->x);
  171.     }
  172.     if (node->left != nullptr) {
  173.         //pair<Node *, long long> resu = sum(node->left, max(l, node->leftBound), min(node->x, r));
  174.         pair<Node *, long long> resu = sum(node->left, max(l, node->left->leftBound), min(node->left->rightBound, r));
  175.         node->left = resu.first;
  176.         rangeCalc(node->left);
  177.         leftSum = resu.second;
  178.     }
  179.     if (node->right != nullptr) {
  180.         //pair<Node *, long long> resu = sum(node->right, max(l, node->x), min(r, node->rightBound));
  181.         pair<Node *, long long> resu = sum(node->right, max(l, node->right->leftBound), min(node->right->rightBound, r));
  182.         node->right = resu.first;
  183.         rangeCalc(node->right);
  184.         rightSum = resu.second;
  185.     }
  186.     rangeCalc(node);
  187.     return make_pair(node, leftSum + rightSum + nodeRes);
  188. }*/
  189.  
  190. pair<Node *, long long> sum(Node *node, long long l, long long r) {
  191.     //TreapNode *t1, *t2, *t3;
  192.     pair<Node *, Node *> res = split(node, l);
  193.     rangeCalc(res.first);
  194.     rangeCalc(res.second);
  195.     pair<Node *, Node *> res1 = split(res.second, r + 1);
  196.     rangeCalc(res1.first);
  197.     rangeCalc(res1.second);
  198.     long long ans = res1.first == nullptr ? 0 : res1.first->sum;
  199.     Node * back = merge(res1.first, res1.second);
  200.     rangeCalc(back);
  201.     node = merge(res.first, back);
  202.     rangeCalc(node);
  203.     return make_pair(node, ans);
  204. }
  205.  
  206. int main() {
  207.     cin >> n;
  208.     long long E = 1e9;
  209.     random_device rd;
  210.     mt19937 mersenne(rd());
  211.     result = 0;
  212.     for (int i = 0; i < n; i++) { //+
  213.         cin >> c;
  214.         cin >> x;
  215.         //if (c == '+' && next(root, (x + result - 1))->x != ((x + result) % 1000000000)) {
  216.         if (c == '+' && !contains(root, (x + result + E) % E)) {
  217.             //
  218.             Node *to = new Node();
  219.             to->x = (x + result + E) % E; //+
  220.             to->sum = to->x; //+
  221.             to->y = mersenne() % 10000000;
  222.             while (a[to->y] != 0) {
  223.                 to->y = mersenne() % 10000000;
  224.             }
  225.             a[to->y]++;
  226.             root = insert(root, to);
  227.             rangeCalc(root);
  228.             result = 0;
  229.         }
  230.         else if (c == '?') {
  231.             cin >> y;
  232.             //y++;
  233.             x %= (E);
  234.             y %= (E);
  235.             pair<Node *, long long> res1 = sum(root, x, y);
  236.             root = res1.first;
  237.             rangeCalc(root);
  238.             result = res1.second;
  239.             cout << result << endl;
  240.         }
  241.     }
  242.     return 0;
  243. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement