cosenza987

Untitled

Jun 4th, 2023
88
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.94 KB | None | 0 0
  1. //Слава Україні, Героям слава
  2.  
  3. #include <bits/stdc++.h>
  4.  
  5. using namespace std;
  6.  
  7. struct seg_tree {
  8.     //modify accordingly
  9.     int n;
  10.     vector<int> v, lz, st;
  11.     void build() {
  12.         build(1, 1, n);
  13.     }
  14.     void build(int p, int l, int r) {
  15.         if(l == r) {
  16.             st[p] = v[l];
  17.             return;
  18.         }
  19.         build(2 * p, l, (l + r) >> 1);
  20.         build(2 * p + 1, ((l + r) >> 1) + 1, r);
  21.         st[p] = st[2 * p] + st[2 * p + 1];
  22.     }
  23.     seg_tree(int n_ = 1) {
  24.         n = n_;
  25.         lz.resize(4 * n);
  26.         st.resize(4 * n);
  27.         v.resize(n + 1);
  28.         build();
  29.     }
  30.     seg_tree(vector<int> &v_) {
  31.         v = v_;
  32.         n = v.size();
  33.         n--;
  34.         lz.resize(4 * n);
  35.         st.resize(4 * n);
  36.         build();
  37.     }
  38.     void push(int p, int l, int r) {
  39.         if(lz[p]) {
  40.             if(l != r) {
  41.                 lz[2 * p] = lz[p];
  42.                 lz[2 * p + 1] = lz[p];
  43.             }
  44.             if(lz[p] == -1) lz[p] = 0;
  45.             st[p] = (r - l + 1) * lz[p];
  46.             lz[p] = 0;
  47.         }
  48.     }
  49.     long long query(int i, int j) {
  50.         return query(i, j, 1, 1, n);
  51.     }
  52.     long long query(int i, int j, int p, int l, int r) {
  53.         push(p, l, r);
  54.         if(l > j or r < i) {
  55.             return 0;
  56.         }
  57.         if(l >= i and j >= r) {
  58.             return st[p];
  59.         }
  60.         return query(i, j, 2 * p, l, (l + r) >> 1) + query(i, j, 2 * p + 1, ((l + r) >> 1) + 1, r);
  61.     }
  62.     void update(int i, int j, int v) {
  63.         update(i, j, v, 1, 1, n);
  64.     }
  65.     void update(int i, int j, int v, int p, int l, int r) {
  66.         push(p, l, r);
  67.         if(l > j or r < i) {
  68.             return;
  69.         }
  70.         if(l >= i and j >= r) {
  71.             lz[p] = v;
  72.             push(p, l, r);
  73.             return;
  74.         }
  75.         update(i, j, v, 2 * p, l, (l + r) >> 1);
  76.         update(i, j, v, 2 * p + 1, ((l + r) >> 1) + 1, r);
  77.         st[p] = st[2 * p] + st[2 * p + 1];
  78.     }
  79. };
  80.  
  81. struct LCA {
  82.     //one indexed shit
  83.     int n, l;
  84.     vector<vector<int>> adj, up;
  85.     vector<int> h;
  86.     LCA (int n_) {
  87.         n = n_;
  88.         l = 31 - __builtin_clz(n);
  89.         adj.resize(n + 1);
  90.         up.assign(n + 1, vector<int>(l + 1));
  91.         h.resize(n + 1);
  92.     }
  93.     void add(int a, int b) {
  94.         adj[a].push_back(b);
  95.         adj[b].push_back(a);
  96.     }
  97.     void dfs(int v = 1, int p = 0, int hh = 0) {
  98.         up[v][0] = p;
  99.         for(int i = 1; i <= l; i++) {
  100.             up[v][i] = up[up[v][i - 1]][i - 1];
  101.         }
  102.         for(auto u : adj[v]) {
  103.             if(u != p) {
  104.                 dfs(u, v, hh + 1);
  105.             }
  106.         }
  107.         h[v] = hh;
  108.     }
  109.     int lca(int a, int b) {
  110.         if(h[a] > h[b]) {
  111.             swap(a, b);
  112.         }
  113.         int dff = h[b] - h[a], cnt = 0;
  114.         while(dff) {
  115.             if(dff & 1) {
  116.                 b = up[b][cnt];
  117.             }
  118.             cnt++;
  119.             dff >>= 1;
  120.         }
  121.         if(a == b) {
  122.             return a;
  123.         }
  124.         for(int i = l; i >= 0; i--) {
  125.             if(up[a][i] != up[b][i]) {
  126.                 a = up[a][i];
  127.                 b = up[b][i];
  128.             }
  129.         }
  130.         return up[a][0];
  131.     }
  132.     int raise(int node, int dist) {
  133.         //if it returns 0, then it fucked up
  134.         int cnt = 0;
  135.         while(dist) {
  136.             if(dist & 1) {
  137.                 node = up[node][cnt];
  138.             }
  139.             cnt++;
  140.             dist >>= 1;
  141.         }
  142.         return node;
  143.     }
  144.     int dist(int a, int b) {
  145.         int z = lca(a, b);
  146.         return h[a] + h[b] - 2 * h[z];
  147.     }
  148. };
  149.  
  150. struct HLD {
  151.     vector<vector<int>> adj;
  152.     vector<int> pos, sz, w, par, h, v;
  153.     seg_tree seg;
  154.     int t;
  155.     HLD(int n) {
  156.         adj.resize(n + 1);
  157.         pos.resize(n + 1); sz.resize(n + 1); w.resize(n + 1); par.resize(n + 1);
  158.         h.resize(n + 1); v.resize(n + 1);
  159.     }
  160.     void build_hld(int k, int p = -1, int f = 1) {
  161.         v[pos[k] = t++] = w[k]; sz[k] = 1;
  162.         for(auto &i : adj[k]) {
  163.             if(i != p) {
  164.                 par[i] = k;
  165.                 h[i] = (i == adj[k][0] ? h[k] : i);
  166.                 build_hld(i, k, f);
  167.                 sz[k] += sz[i];
  168.                 if(sz[i] > sz[adj[k][0]] or adj[k][0] == p) {
  169.                     swap(i, adj[k][0]);
  170.                 }
  171.             }
  172.         }
  173.         if(p * f == -1) {
  174.             t = 1;
  175.             build_hld(h[k] = k, -1, 0);
  176.         }
  177.     }
  178.     void add(int a, int b) {
  179.         adj[a].push_back(b);
  180.         adj[b].push_back(a);
  181.     }
  182.     void build(int root = 1) {
  183.         t = 1;
  184.         build_hld(root);
  185.         seg = seg_tree(v);
  186.     }
  187.     long long query_path(int a, int b) {
  188.         if(pos[a] < pos[b]) swap(a, b);
  189.         if(h[a] == h[b]) return seg.query(pos[b], pos[a]);
  190.         return seg.query(pos[h[a]], pos[a]) + query_path(par[h[a]], b);
  191.     }
  192.     void update_path(int a, int b, int x) {
  193.         if(pos[a] < pos[b]) swap(a, b);
  194.         if(h[a] == h[b]) {
  195.             seg.update(pos[b], pos[a], x);
  196.             return;
  197.         }
  198.         seg.update(pos[h[a]], pos[a], x);
  199.         update_path(par[h[a]], b, x);
  200.     }
  201.     long long query_subtree(int a) {
  202.         return seg.query(pos[a], pos[a] + sz[a] - 1);
  203.     }
  204.     void update_subtree(int a, int x) {
  205.         seg.update(pos[a], pos[a] + sz[a] - 1, x);
  206.     }
  207. };
  208.  
  209. int main() {
  210.     ios_base::sync_with_stdio(false);
  211.     cin.tie(nullptr);
  212.     int n;
  213.     cin >> n;
  214.     LCA lca(n);
  215.     HLD hld(n);
  216.     vector<int> posl(n + 1), posr(n + 1);
  217.     int t = 1;
  218.     for(int i = 1; i < n; i++) {
  219.         int a, b;
  220.         cin >> a >> b;
  221.         lca.add(a, b);
  222.         hld.add(a, b);
  223.     }
  224.     lca.dfs();
  225.     hld.build();
  226.     function<int(int, int)> dfs = [&](int u, int p) {
  227.         posl[u] = t;
  228.         bool foi = false;
  229.         for(auto e : lca.adj[u]) {
  230.             if(e != p) {
  231.                 foi = true;
  232.                 posr[u] = max(posr[u], dfs(e, u));
  233.             }
  234.         }
  235.         if(!foi) posr[u] = t++;
  236.         return posr[u];
  237.     };
  238.     dfs(1, 0);
  239.     seg_tree leaves(t);
  240.     int q;
  241.     cin >> q;
  242.     while(q--) {
  243.         int a, b;
  244.         cin >> a >> b;
  245.         if(a == 1) {
  246.             int l = 0, r = lca.h[b], ans = 0;
  247.             leaves.update(posl[b], posr[b], 1);
  248.             hld.update_subtree(b, 1);
  249.             while(l <= r) {
  250.                 int m = (l + r) >> 1;
  251.                 int mid = lca.raise(b, m);
  252.                 if(leaves.query(posl[mid], posr[mid]) == posr[mid] - posl[mid] + 1) {
  253.                     ans = mid;
  254.                     l = m + 1;
  255.                 } else {
  256.                     r = m - 1;
  257.                 }
  258.             }
  259.             hld.update_path(ans, b, 1);
  260.         } else if(a == 2) {
  261.             leaves.update(posl[b], posr[b], -1);
  262.             hld.update_subtree(b, -1);
  263.             hld.update_path(1, b, -1);
  264.         } else {
  265.             cout << hld.query_subtree(b) << "\n";
  266.         }
  267.     }
  268.     return 0;
  269. }
Add Comment
Please, Sign In to add comment