Advertisement
pasholnahuy

Сумма на отрезке, прибавление на отрезке (запросы)

Oct 13th, 2023
1,444
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.94 KB | None | 0 0
  1. #include <iostream>
  2. #include <tuple>
  3. #include <random>
  4.  
  5. using std::pair;
  6. using std::cin;
  7. using std::cout;
  8. using std::vector;
  9. using int64 = int64_t;
  10. using std::max;
  11. using std::min;
  12.  
  13. class SegmentTree {
  14. public:
  15.     int64 log_size;
  16.     vector<int64> nodes = std::vector<int64>((2 << log_size) - 1);
  17.     vector<int64> SubtreeAdd = std::vector<int64>((2 << log_size) - 1);
  18.  
  19.     static int64 IntLog(int64 n) {
  20.         int64 temp = 1;
  21.         int64 ans = 0;
  22.         while (temp < n) {
  23.             temp *= 2;
  24.             ++ans;
  25.         }
  26.         return ans;
  27.     }
  28.  
  29.     static int64 Pow2(int64 n) {
  30.         return 1 << n;
  31.     }
  32.  
  33.     explicit SegmentTree(const vector<int64> &vec) : log_size(IntLog(vec.size())) {
  34.         std::copy(vec.begin(), vec.end(), nodes.begin() + (1 << log_size) - 1);
  35.         for (int64 i = Pow2(log_size) - 2; i >= 0; --i) {
  36.             nodes[i] = nodes[2 * i + 1] + nodes[2 * i + 2];
  37.         }
  38.     }
  39.  
  40.     void Modify(int64 l, int64 r, int64 val) {
  41.         Modify(l, r, 0, 0, Pow2(log_size) - 1, val);
  42.     }
  43.  
  44.     int64 GetSum(int64 l, int64 r) {
  45.         return GetSum(l, r, 0, 0, Pow2(log_size) - 1);
  46.     }
  47.  
  48. private:
  49.  
  50.     int64 GetSum(int64 l, int64 r, int64 n, int64 nl, int64 nr) {
  51.         push(n, nl, nr);
  52.         if (l > r) {
  53.             return 0;
  54.         }
  55.         if (l == nl && r == nr) {
  56.             return nodes[n];
  57.         }
  58.         int64 mid = (nl + nr) / 2;
  59.         return GetSum(l, min(r, mid), n * 2 + 1, nl, mid) +
  60.                GetSum(max(l, mid + 1), r, n * 2 + 2, mid + 1, nr);
  61.     }
  62.  
  63.     void push(int64 v, int64 vl, int64 vr) {
  64.         if (SubtreeAdd[v]) {
  65.             nodes[v] += SubtreeAdd[v] * (vr - vl + 1);
  66.             if (vl != vr) {
  67.                 SubtreeAdd[2 * v + 1] += SubtreeAdd[v];
  68.                 SubtreeAdd[2 * v + 2] += SubtreeAdd[v];
  69.             }
  70.             SubtreeAdd[v] = 0;
  71.         }
  72.     }
  73.  
  74.     void Modify(int64 l, int64 r, int64 n, int64 nl, int64 nr, int64 val) {
  75.         push(n, nl, nr);
  76.         if (l > nr || r < nl) {
  77.             return;
  78.         }
  79.         if (l <= nl && r >= nr) {
  80.             SubtreeAdd[n] += val;
  81.             push(n, nl, nr);
  82.             return;
  83.         } else {
  84.             int64 mid = (nl + nr) / 2;
  85.             Modify(l, r, n * 2 + 1, nl, mid, val);
  86.             Modify(l, r, n * 2 + 2, mid + 1, nr, val);
  87.             nodes[n] = nodes[2 * n + 1] + nodes[2 * n + 2];
  88.         }
  89.     }
  90.  
  91.  
  92. };
  93.  
  94. int main() {
  95.     int64 n;
  96.     cin >> n;
  97.     vector<int64> vec(n);
  98.     for (size_t i = 0; i < n; ++i) {
  99.         cin >> vec[i];
  100.     }
  101.     SegmentTree st(vec);
  102.     int k;
  103.     cin >> k;
  104.     for (size_t i = 0; i < k; ++i) {
  105.         int num;
  106.         cin >> num;
  107.         if (num == 1) {
  108.             int64 l, r;
  109.             cin >> l >> r;
  110.             cout << st.GetSum(l, r) << '\n';
  111.         } else {
  112.             int64 l, r, x;
  113.             cin >> l >> r >> x;
  114.             st.Modify(l, r, x);
  115.         }
  116.     }
  117.     return 0;
  118. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement