Advertisement
matheus_monteiro

Soma de Somas

Apr 15th, 2022
98
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.84 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. const long long mod = 1000000007;
  6.  
  7. class Node {
  8. public:
  9.     long long ans;
  10.     long long sum;
  11.     long long pre;
  12.     long long suf;
  13.     int size;
  14.  
  15.     Node(long long value) : ans(value), sum(value), pre(value), suf(value), size(1) {}
  16.     Node() : ans(0), sum(0), pre(0), suf(0), size(0) {}
  17. };
  18.  
  19. class SegmentTree {
  20. private:
  21.     int n;
  22.     vector<Node> tree;
  23.  
  24.     Node merge(Node nodeLeft, Node nodeRight) {
  25.         Node mergeNode;
  26.         mergeNode.ans = (((nodeRight.size * nodeLeft.suf) % mod) + ((nodeLeft.size * nodeRight.pre) % mod) + ((nodeLeft.ans + nodeRight.ans) % mod)) % mod;
  27.         mergeNode.sum = (nodeLeft.sum + nodeRight.sum) % mod;
  28.         mergeNode.pre = nodeLeft.pre + nodeRight.pre;
  29.         mergeNode.pre += nodeRight.size * nodeLeft.sum;
  30.         mergeNode.suf = nodeLeft.suf + nodeRight.suf;
  31.         mergeNode.suf += nodeLeft.size * nodeRight.sum;
  32.         mergeNode.pre %= mod;
  33.         mergeNode.suf %= mod;
  34.         mergeNode.size = nodeLeft.size + nodeRight.size;
  35.         return mergeNode;
  36.     }
  37.  
  38.     void build(int node, int start, int end, const vector<long long> &vet) {
  39.         if(start == end) {
  40.             tree[node] = Node(vet[start]);
  41.             return;
  42.         }
  43.         int mid = (start + end) / 2;
  44.         build(2 * node, start, mid, vet);
  45.         build(2 * node + 1, mid + 1, end, vet);
  46.         tree[node] = merge(tree[2 * node], tree[2 * node + 1]);
  47.     }
  48.  
  49.     Node query(int node, int start, int end, int l, int r) {
  50.         if(start > r or end < l) {
  51.             return Node();
  52.         }
  53.         if(l <= start and end <= r) {
  54.             return tree[node];
  55.         }
  56.         int mid = (start + end) / 2;
  57.         Node queryLeft = query(2 * node, start, mid, l, r);
  58.         Node queryRight = query(2 * node + 1, mid + 1, end, l, r);
  59.         return merge(queryLeft, queryRight);
  60.     }
  61.  
  62.     void update(int node, int start, int end, int idx, int val) {
  63.         if(start == end) {
  64.             tree[node] = Node((val + tree[node].ans) % mod);
  65.             return;
  66.         }
  67.         int mid = (start + end) / 2;
  68.         if(idx <= mid) {
  69.             update(2 * node, start, mid, idx, val);
  70.         } else {
  71.             update(2 * node + 1, mid + 1, end, idx, val);
  72.         }
  73.         tree[node] = merge(tree[2 * node], tree[2 * node + 1]);
  74.     }
  75.  
  76. public:
  77.     void update(int position, int value) {
  78.         update(1, 0, n - 1, position - 1, value);
  79.     }
  80.  
  81.     long long query(int l, int r) {
  82.         return query(1, 0, n - 1, l - 1, r - 1).ans;
  83.     }
  84.  
  85.     SegmentTree(const vector<long long> &vet) {
  86.         n = vet.size();
  87.         tree.resize(4 * n);
  88.         build(1, 0, n - 1, vet);
  89.     }
  90. };
  91.  
  92. int32_t main() {
  93.     ios_base::sync_with_stdio(false);
  94.  
  95.     int n, m;
  96.  
  97.     cin >> n >> m;
  98.  
  99.     vector<long long> arr(n);
  100.  
  101.     for(long long &w : arr)
  102.         cin >> w;
  103.  
  104.     SegmentTree tree(arr);
  105.  
  106.     for(int i = 0; i < m; ++i) {
  107.         int o;
  108.         cin >> o;
  109.         if(o == 1) {
  110.             int leftPos;
  111.             int rightPos;
  112.             cin >> leftPos >> rightPos;
  113.             cout << tree.query(leftPos, rightPos) << '\n';
  114.         } else {
  115.             int position;
  116.             int value;
  117.             cin >> position >> value;
  118.             tree.update(position, value);
  119.         }
  120.     }
  121.  
  122.     return 0;
  123. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement