Alex_tz307

Codeforces SegTree - part 2 - step 4 - B

Sep 25th, 2020 (edited)
154
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.76 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. #define int unsigned long long int
  3.  
  4. using namespace std;
  5.  
  6. /*
  7. So make things easier you can firstly consider 3 lazy values instead of the two that I used(later we will combine two of them into a single one):
  8. l1 - sum of values a
  9. l2 - sum of values d
  10. l3 - sum of values d * l.
  11. The update for a node which has ends of interval [L, R] will be:
  12. node += (R - L + 1) * l1 + (R * (R + 1) - L * (L - 1)) / 2 * l2 - (R - L + 1) * l3,
  13. so the first term of the sum is obvious because (R - L + 1) is the length of the segment(I use 1 - indexing) and for each element of the segment you have to add a, so for the whole segment you add len_seg(R - L + 1) * a(l1 in our case because there may be more update operations added in l1)
  14. The third one is easy too. If we were to rewrite the statement update operation we would get: xi += a + d * i - d * l, so this is the same case as for a. You just have to subtract
  15. len_seg(R - L + 1) * l3. Also, we observe that l1 and l3 have the same coefficient so we can
  16. combine them in only one lazy value(in my code this value is lazy[x].first)
  17. Finally, the second one is easy again:). We have the sum of d in l2. If we want
  18. to update the segment [L, R] will need to add L * l2 + (L + 1) * l2 + ... + R * l2 =
  19. = l2 * (L + (L + 1) + ... + R) = l2 * ((1 + 2 + ... + R) - (1 + 2 + ... + (L - 1)) =
  20. = l2 * (R * (R + 1) - L * (L - 1)) / 2 (using Gauss's formula). In my code l2 is lazy[x].second.
  21. */
  22.  
  23. struct SegTree {
  24.     int Size;
  25.     vector < int > Tree;
  26.     vector < pair < int , int > > lazy;
  27.  
  28.     void init(int N) {
  29.         Size = 1;
  30.         while(Size < N)
  31.             Size <<= 1;
  32.         Tree.assign((Size << 1) + 1, 0);
  33.         lazy.assign((Size << 1) + 1, make_pair(0, 0));
  34.     }
  35.  
  36.     void propagate(int x, int lx, int rx) {
  37.         if(lx == rx)
  38.             return;
  39.         int mid = (lx + rx) >> 1;
  40.         int len1 = mid - lx + 1;
  41.         int len2 = rx - mid;
  42.         Tree[x << 1] += len1 * lazy[x].first + (mid * (mid + 1) - lx * (lx - 1)) / 2 * lazy[x].second;
  43.         Tree[(x << 1) + 1] += len2 * lazy[x].first + (rx * (rx + 1) - mid * (mid + 1)) / 2 * lazy[x].second;
  44.         lazy[x << 1].first += lazy[x].first;
  45.         lazy[x << 1].second += lazy[x].second;
  46.         lazy[(x << 1) + 1].first += lazy[x].first;
  47.         lazy[(x << 1) + 1].second += lazy[x].second;
  48.         lazy[x] = make_pair(0, 0);
  49.     }
  50.  
  51.     void update(int x, int lx, int rx, int st, int dr, int a, int d) {
  52.         propagate(x, lx, rx);
  53.         if(st <= lx && rx <= dr) {
  54.             int len = rx - lx + 1;
  55.             Tree[x] += len * (a - d * st) + ((rx * (rx + 1) - lx * (lx - 1)) / 2 * d);
  56.             lazy[x].first += (a - d * st);
  57.             lazy[x].second += d;
  58.             return;
  59.         }
  60.         int mid = (lx + rx) >> 1;
  61.         if(st <= mid)
  62.             update(x << 1, lx, mid, st, dr, a, d);
  63.         if(mid < dr)
  64.             update((x << 1) + 1, mid + 1, rx, st, dr, a, d);
  65.     }
  66.  
  67.     int query(int x, int lx, int rx, int poz) {
  68.         propagate(x, lx, rx);
  69.         if(lx == rx)
  70.             return Tree[x];
  71.         int mid = (lx + rx) >> 1;
  72.         if(poz <= mid)
  73.             return query(x << 1, lx, mid, poz);
  74.         else
  75.             return query((x << 1) + 1, mid + 1, rx, poz);
  76.     }
  77. };
  78.  
  79. int32_t main() {
  80.     ios_base::sync_with_stdio(false);
  81.     cin.tie(nullptr);
  82.     cout.tie(nullptr);
  83.     int N, Q;
  84.     cin >> N >> Q;
  85.     SegTree Tree;
  86.     Tree.init(N);
  87.     while(Q --) {
  88.         int type;
  89.         cin >> type;
  90.         if(type == 1) {
  91.             int st, dr, a, d;
  92.             cin >> st >> dr >> a >> d;
  93.             Tree.update(1, 1, N, st, dr, a, d);
  94.         }
  95.         else {
  96.             int poz;
  97.             cin >> poz;
  98.             cout << Tree.query(1, 1, N, poz) << '\n';
  99.         }
  100.     }
  101. }
  102.  
Advertisement
Add Comment
Please, Sign In to add comment