cosenza987

Untitled

Oct 15th, 2025
213
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.21 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<unsigned long long> 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<unsigned long long> &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.             st[p] = (r - l + 1) * lz[p];
  41.             if(l != r) {
  42.                 lz[2 * p] = lz[p];
  43.                 lz[2 * p + 1] = lz[p];
  44.             }
  45.             lz[p] = 0;
  46.         }
  47.     }
  48.     unsigned long long query(int i, int j) {
  49.         return query(i, j, 1, 1, n);
  50.     }
  51.     unsigned long long query(int i, int j, int p, int l, int r) {
  52.         push(p, l, r);
  53.         if(l > j or r < i) {
  54.             return 0;
  55.         }
  56.         if(l >= i and j >= r) {
  57.             return st[p];
  58.         }
  59.         return query(i, j, 2 * p, l, (l + r) >> 1) + query(i, j, 2 * p + 1, ((l + r) >> 1) + 1, r);
  60.     }
  61.     void update(int i, int j, unsigned long long v) {
  62.         update(i, j, v, 1, 1, n);
  63.     }
  64.     void update(int i, int j, unsigned long long v, int p, int l, int r) {
  65.         push(p, l, r);
  66.         if(l > j or r < i) {
  67.             return;
  68.         }
  69.         if(l >= i and j >= r) {
  70.             lz[p] = v;
  71.             push(p, l, r);
  72.             return;
  73.         }
  74.         update(i, j, v, 2 * p, l, (l + r) >> 1);
  75.         update(i, j, v, 2 * p + 1, ((l + r) >> 1) + 1, r);
  76.         st[p] = st[2 * p] + st[2 * p + 1];
  77.     }
  78. };
  79.  
  80. template <bool EDGE> struct HLD {
  81.     vector<vector<int>> g1;
  82.     vector<vector<pair<int, int>>> g2;
  83.     vector<int> pos, sz, par, h;
  84.     vector<unsigned long long> v, w, sobe;
  85.     seg_tree seg;
  86.     int t;
  87.     HLD(int n) {
  88.         if(EDGE) {
  89.             g2.resize(n + 3);
  90.         } else {
  91.             g1.resize(n + 3);
  92.         }
  93.         pos.resize(n + 3); sz.resize(n + 3); par.resize(n + 3);
  94.         if(EDGE) {
  95.             sobe.resize(n + 3);
  96.         } else {
  97.             w.resize(n + 3);
  98.         }
  99.         h.resize(n + 3); v.resize(n + 3);
  100.     }
  101.     void build_hld(int k, int p = -1, int f = 1) {
  102.         v[pos[k] = t++] = (EDGE ? sobe : w)[k]; sz[k] = 1;
  103.         for(int i = 0; i < (int)(EDGE ? g2[k].size() : g1[k].size()); i++) {
  104.             if((EDGE and g2[k][i].first != p) or (!EDGE and g1[k][i] != p)) {
  105.                 if(EDGE) {
  106.                     sobe[g2[k][i].first] = g2[k][i].second; par[g2[k][i].first] = k;
  107.                     h[g2[k][i].first] = (g2[k][i] == g2[k][0] ? h[k] : g2[k][i].first);
  108.                     build_hld(g2[k][i].first, k, f); sz[k] += sz[g2[k][i].first];
  109.                     if(sz[g2[k][i].first] > sz[g2[k][0].first] or g2[k][0].first == p) {
  110.                         swap(g2[k][i], g2[k][0]);
  111.                     }
  112.                 } else {
  113.                     par[g1[k][i]] = k;
  114.                     h[g1[k][i]] = (g1[k][i] == g1[k][0] ? h[k] : g1[k][i]);
  115.                     build_hld(g1[k][i], k, f);
  116.                     sz[k] += sz[g1[k][i]];
  117.                     if(sz[g1[k][i]] > sz[g1[k][0]] or g1[k][0] == p) {
  118.                         swap(g1[k][i], g1[k][0]);
  119.                     }
  120.                 }
  121.             }
  122.         }
  123.         if(p * f == -1) {
  124.             t = 1;
  125.             build_hld(h[k] = k, -1, 0);
  126.         }
  127.     }
  128.     void add(int a, int b) {
  129.         g1[a].push_back(b);
  130.         g1[b].push_back(a);
  131.     }
  132.     void add(int a, int b, int x) {
  133.         g2[a].push_back({b, x});
  134.         g2[b].push_back({a, x});
  135.     }
  136.     void build(int root = 1) {
  137.         t = 1;
  138.         build_hld(root);
  139.         seg = seg_tree(v);
  140.     }
  141.     unsigned long long query_path(int a, int b) {
  142.         if(EDGE and a == b) return 0;
  143.         if(pos[a] < pos[b]) swap(a, b);
  144.         if(h[a] == h[b]) return seg.query(pos[b] + EDGE, pos[a]);
  145.         return seg.query(pos[h[a]], pos[a]) + query_path(par[h[a]], b);
  146.     }
  147.     void update_path(int a, int b, unsigned long long x) {
  148.         if(EDGE and a == b) return;
  149.         if(pos[a] < pos[b]) swap(a, b);
  150.         if(h[a] == h[b]) {
  151.             seg.update(pos[b] + EDGE, pos[a], x);
  152.             return;
  153.         }
  154.         seg.update(pos[h[a]], pos[a], x);
  155.         update_path(par[h[a]], b, x);
  156.     }
  157.     unsigned long query_subtree(int a) {
  158.         if(EDGE and sz[a] == 1) return 0;
  159.         return seg.query(pos[a] + EDGE, pos[a] + sz[a] - 1);
  160.     }
  161.     void update_subtree(int a, int x) {
  162.         if(EDGE and sz[a] == 1) return;
  163.         seg.update(pos[a] + EDGE, pos[a] + sz[a] - 1, x);
  164.     }
  165. };
  166.  
  167. using ull = unsigned long long;
  168.  
  169. random_device rd;
  170. mt19937 gen(rd());
  171. uniform_int_distribution<ull> distrib(0, ULLONG_MAX);
  172.  
  173. int main() {
  174.     ios_base::sync_with_stdio(false);
  175.     cin.tie(nullptr);
  176.     int t;
  177.     cin >> t;
  178.     while(t--) {
  179.         int n, q;
  180.         cin >> n >> q;
  181.         vector<unsigned long long> v(n + 3);
  182.         vector<unsigned long long> hsh(n + 1), perm(n + 1);
  183.         set<unsigned long long> st;
  184.         for(int i = 1; i <= n; i++) {
  185.             cin >> v[i];
  186.             hsh[i] = distrib(gen);
  187.             perm[i] = perm[i - 1] + hsh[i];
  188.             st.insert(perm[i]);
  189.         }
  190.         HLD<false> hld(n);
  191.         for(int i = 1; i <= n; i++) hld.w[i] = hsh[v[i]];
  192.         for(int i = 1; i < n; i++) {
  193.             int a, b;
  194.             cin >> a >> b;
  195.             hld.add(a, b);
  196.         }
  197.         hld.build();
  198.         while(q--) {
  199.             int t, a, b;
  200.             cin >> t >> a >> b;
  201.             if(t == 1) {
  202.                 unsigned long long x = hld.query_path(a, b);
  203.                 cout << (st.find(x) != st.end() ? "Yes\n" : "No\n");
  204.             } else {
  205.                 hld.update_path(a, a, hsh[b]);
  206.             }
  207.         }
  208.     }
  209.     return 0;
  210. }
Advertisement
Add Comment
Please, Sign In to add comment