leoanjos

Fig trees of Hatshepsut

Jul 7th, 2023
1,202
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.38 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. #define llong long long int
  6.  
  7. const int MAX = 1e6 + 5;
  8.  
  9. int phi[MAX];
  10.  
  11. struct SegmentTree {
  12. private:
  13.     struct Node {
  14.         llong sum;
  15.         int equal;
  16.  
  17.         Node(llong sum = 0LL, int equal = -1): sum(sum), equal(equal) {}
  18.  
  19.         Node operator +(Node other) {
  20.             llong nsum = sum + other.sum;
  21.             int nequal = equal == -1 || other.equal == -1 ? -1 : (equal != other.equal ? -1 : equal);
  22.             return Node(nsum, nequal);
  23.         }
  24.     };
  25.  
  26.     int n;
  27.     vector<int> a;
  28.     vector<int> lazy;
  29.     vector<Node> tree;
  30.  
  31. public:
  32.     SegmentTree(int n, vector<int> &a) {
  33.         this->n = n;
  34.         this->a = a;
  35.  
  36.         lazy.assign(4 * n, -1);
  37.         tree.resize(4 * n);
  38.         build(1, 1, n);
  39.     }
  40.  
  41.     void update(int l, int r, int v = -1) {
  42.         update(1, 1, n, l, r, v);
  43.     }
  44.  
  45.     llong query(int l, int r) {
  46.         return query(1, 1, n, l, r);
  47.     }
  48.  
  49. private:
  50.     void build(int node, int l, int r) {
  51.         if (l == r) tree[node] = Node(a[l], a[l]);
  52.         else {
  53.             int m = (l + r) / 2;
  54.             build(2 * node, l, m);
  55.             build(2 * node + 1, m + 1, r);
  56.             tree[node] = tree[2 * node] + tree[2 * node + 1];
  57.         }
  58.     }
  59.  
  60.     void update_lazy(int node, int l, int r, int v) {
  61.         tree[node].sum = (r - l + 1LL) * v;
  62.         tree[node].equal = v;
  63.         lazy[node] = v;
  64.     }
  65.  
  66.     void push_down(int node, int l, int r) {
  67.         if (lazy[node] == -1) return;
  68.  
  69.         int m = (l + r) / 2;
  70.         update_lazy(2 * node, l, m, lazy[node]);
  71.         update_lazy(2 * node + 1, m + 1, r, lazy[node]);
  72.         lazy[node] = -1;
  73.     }
  74.  
  75.     void update(int node, int l, int r, int ul, int ur, int v) {
  76.         if (r < ul || l > ur) return;
  77.         if (ul <= l && r <= ur) {
  78.             if (v != -1) {
  79.                 update_lazy(node, l, r, v);
  80.                 return;
  81.             }
  82.  
  83.             if (tree[node].equal != -1) {
  84.                 update_lazy(node, l, r, phi[tree[node].equal]);
  85.                 return;
  86.             }
  87.         }
  88.  
  89.         push_down(node, l, r);
  90.  
  91.         int m = (l + r) / 2;
  92.         update(2 * node, l, m, ul, ur, v);
  93.         update(2 * node + 1, m + 1, r, ul, ur, v);
  94.         tree[node] = tree[2 * node] + tree[2 * node + 1];
  95.     }
  96.  
  97.     llong query(int node, int l, int r, int ql, int qr) {
  98.         if (r < ql || l > qr) return 0LL;
  99.         if (ql <= l && r <= qr) return tree[node].sum;
  100.  
  101.         push_down(node, l, r);
  102.  
  103.         int m = (l + r) / 2;
  104.         return query(2 * node, l, m, ql, qr) + query(2 * node + 1, m + 1, r, ql, qr);
  105.     }
  106. };
  107.  
  108. int main() {
  109.     ios_base::sync_with_stdio(false);
  110.     cin.tie(NULL);
  111.  
  112.     for (int i = 0; i < MAX; i++)
  113.         phi[i] = i;
  114.  
  115.     for (int i = 2; i < MAX; i++)
  116.         if (phi[i] == i)
  117.             for (int j = i; j < MAX; j += i)
  118.                 phi[j] -= phi[j] / i;
  119.  
  120.     int n, q;
  121.     cin >> n >> q;
  122.  
  123.     vector<int> a(n + 1);
  124.     for (int i = 1; i <= n; i++)
  125.         cin >> a[i];
  126.  
  127.     SegmentTree tree(n, a);
  128.     while (q--) {
  129.         int t, L, R;
  130.         cin >> t >> L >> R;
  131.  
  132.         if (t == 1) tree.update(L, R);
  133.         else if (t == 2) {
  134.             int x; cin >> x;
  135.             tree.update(L, R, x);
  136.         }
  137.         else {
  138.             llong ans = tree.query(L, R);
  139.             cout << ans << "\n";
  140.         }
  141.     }
  142. }
Advertisement
Add Comment
Please, Sign In to add comment