Advertisement
slash0t

virtual tree

Feb 18th, 2025 (edited)
99
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.18 KB | None | 0 0
  1. struct tree {
  2.     vector<vector<int>> jump;
  3.     vector<vector<pair<int, int>>> g;
  4.     vector<int> depth, in, out;
  5.     vector<bool> flag;
  6.     int root, n, logn = 32;
  7.     int time = 0, szflag = 0;
  8.  
  9.  
  10.     tree(int nn, int r = 0) : root(r), n(nn) {
  11.         g.assign(n, vector<pair<int, int>>());
  12.         flag.assign(n, 0);
  13.     }
  14.  
  15.     void add_edge(int a, int b, int w = 1) {
  16.         g[a].pb({ b, w });
  17.         g[b].pb({ a, w });
  18.     }
  19.  
  20.     void count_euler(int now = -1, int prev = -1) {
  21.         if (now == -1) {
  22.             now = root;
  23.             time = 0;
  24.             in.assign(n, 0);
  25.             out.assign(n, 0);
  26.         }
  27.  
  28.         in[now] = time++;
  29.         for (auto& to : g[now]) {
  30.             if (to.xx == prev) continue;
  31.             count_euler(to.xx, now);
  32.         }
  33.         out[now] = time++;
  34.     }
  35.  
  36.     void count_depth(int now = -1, int prev = -1, int d = 0) {
  37.         if (now == -1) {
  38.             now = root;
  39.             depth.assign(n, 0);
  40.         }
  41.  
  42.         depth[now] = d;
  43.         for (auto& to : g[now]) {
  44.             if (to.xx == prev) continue;
  45.             count_depth(to.xx, now, d + 1);
  46.         }
  47.     }
  48.  
  49.     void count_parents(int now = -1, int prev = -1) {
  50.         if (now == -1) {
  51.             now = root;
  52.             jump[now][0] = root;
  53.         }
  54.         else {
  55.             jump[now][0] = prev;
  56.         }
  57.  
  58.         for (auto& to : g[now]) {
  59.             if (to.xx == prev) continue;
  60.             count_parents(to.xx, now);
  61.         }
  62.     }
  63.  
  64.     void count_lca() {
  65.         jump.assign(n, vector<int>(logn));
  66.         count_parents();
  67.         count_depth();
  68.  
  69.         for (int i = 1; i < logn; i++) {
  70.             for (int j = 0; j < n; j++) {
  71.                 jump[j][i] = jump[jump[j][i - 1]][i - 1];
  72.             }
  73.         }
  74.     }
  75.  
  76.     int lca(int a, int b) {
  77.         if (depth[a] < depth[b]) swap(a, b);
  78.  
  79.         for (int i = logn - 1; i >= 0; i--) {
  80.             if (depth[jump[a][i]] < depth[b]) continue;
  81.             a = jump[a][i];
  82.         }
  83.  
  84.         if (a == b) return a;
  85.  
  86.         for (int i = logn - 1; i >= 0; i--) {
  87.             if (jump[a][i] == jump[b][i]) continue;
  88.             a = jump[a][i];
  89.             b = jump[b][i];
  90.         }
  91.  
  92.         return jump[a][0];
  93.     }
  94.  
  95.     tree get_aux(vector<int>& s) {
  96.         if (jump.empty()) count_lca();
  97.         if (in.empty()) count_euler();
  98.  
  99.         vector<pair<int, int>> a;
  100.         for (int i : s) a.pb({ in[i], i });
  101.         sortt(a);
  102.         for (int i = 1; i < s.size(); i++) {
  103.             int lcaa = lca(a[i].yy, a[i - 1].yy);
  104.             a.pb({ in[lcaa], lcaa });
  105.         }
  106.         sortt(a);
  107.         a.erase(unique(a.begin(), a.end()), a.end());
  108.  
  109.         tree res(a.size());
  110.         stack<int> st;
  111.         st.push(0);
  112.         for (int i = 1; i < a.size(); i++) {
  113.             int curr = a[i].yy;
  114.             int top = a[st.top()].yy;
  115.             while (in[top] > in[curr] || out[top] < in[curr]) {
  116.                 st.pop();
  117.                 top = a[st.top()].yy;
  118.             }
  119.             res.add_edge(i, st.top(), depth[curr] - depth[top]);
  120.             st.push(i);
  121.         }
  122.         vector<pair<int, int>> b;
  123.         for (int i = 0; i < a.size(); i++) b.pb({ a[i].yy, i });
  124.         sort(b.begin(), b.end());
  125.         sort(s.begin(), s.end());
  126.         int i = 0, j = 0;
  127.         while (i < s.size() && j < a.size()) {
  128.             if (s[i] == b[j].xx) {
  129.                 res.flag[b[j].yy] = 1;
  130.                 i++, j++;
  131.             }
  132.             else if (s[i] < b[j].xx) i++;
  133.             else j++;
  134.         }
  135.         res.szflag = s.size();
  136.         return res;
  137.     }
  138.  
  139.     int count_marked(int& answer, int now = -1, int prev = -1) {
  140.         if (now == -1) {
  141.             now = root;
  142.         }
  143.         int res = flag[now];
  144.  
  145.         for (auto& to : g[now]) {
  146.             if (to.xx == prev) continue;
  147.             int temp = count_marked(answer, to.xx, now);
  148.             res += temp;
  149.  
  150.             answer += temp * (szflag - temp) * to.yy;
  151.         }
  152.  
  153.         return res;
  154.     }
  155. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement