prog3r

C

Feb 6th, 2026
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.25 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. signed main() {
  4.     ios::sync_with_stdio(0);
  5.     cin.tie(0);
  6.     struct Edge {
  7.         int u, v, ql, qr, length;
  8.     };
  9.     int n, q;
  10.     cin >> n >> q;
  11.     vector<array<int,3>> ask(q+1, {-888,-888,-888});
  12.     vector<string> tp(q+1);
  13.     vector<int> ans(q+1, -999);
  14.     vector<int> seen(n+1); // {dfs_id}
  15.     vector<int> is_key(n+1); // {dfs_id}
  16.     vector<int> keys_in_subtree(n+1); // {dfs_id}
  17.     vector<int> up(n+1);
  18.     auto LCA = [&] (int u, int v) -> int {
  19.         vector<int> up_u = {u}; while (up[u]) up_u.push_back(u = up[u]);
  20.         vector<int> up_v = {v}; while (up[v]) up_v.push_back(v = up[v]);
  21.         int ret = -1;
  22.         while (up_u.size() && up_v.size() && up_u.back() == up_v.back()) {
  23.             ret = up_u.back();
  24.             up_u.pop_back(), up_v.pop_back();
  25.         }
  26.         return ret;
  27.     };
  28.     vector<pair<vector<pair<int,int>>,int>> adj(n+1); // {{length,to}, dfs_id}
  29.     int dfs_id = 0;
  30.     auto go = [&] (auto f, int tl, int tr, vector<Edge> edges) -> void {
  31.         dfs_id += 1;
  32.         int tm = (tl + tr) >> 1;
  33.         for (int i = tl; i <= tr; i += 1) {
  34.             if (tp[i] != "lca") {
  35.                 continue;
  36.             }
  37.             for (const auto &x : ask[i]) {
  38.                 up[x] = 0;
  39.                 is_key[x] = dfs_id;
  40.             }
  41.         }
  42.         vector<Edge> to_l, to_r;
  43.         vector<int> start_from;
  44.         for (const auto &[u, v, l, r, length] : edges) {
  45.             if (l<=tl&&tr<=r) {
  46.                 start_from.push_back(u);
  47.                 start_from.push_back(v);
  48.                 if (adj[u].second != dfs_id) {
  49.                     adj[u].second = dfs_id;
  50.                     adj[u].first.clear();
  51.                 }adj[u].first.push_back({length, v});
  52.                 if (adj[v].second != dfs_id) {
  53.                     adj[v].second = dfs_id;
  54.                     adj[v].first.clear();
  55.                 }adj[v].first.push_back({length, u});
  56.             } else {
  57.                 is_key[u] = dfs_id;
  58.                 is_key[v] = dfs_id;
  59.                 if (l <= tm) {
  60.                     to_l.push_back({u,v,l,min(r,tm),length});
  61.                 }
  62.                 if (r >= tm+1) {
  63.                     to_r.push_back({u,v,max(l, tm+1),r,length});
  64.                 }
  65.             }
  66.         }
  67.         auto find_keys = [&] (auto f, int u, int p) -> bool {
  68.             seen[u] = dfs_id;
  69.             bool ret = is_key[u] == dfs_id;
  70.             for (const auto &x : adj[u].first) {
  71.                 if (x.second != p) {
  72.                     up[x.second] = u;
  73.                     ret |= f(f, x.second, u);
  74.                 }
  75.             }
  76.             if (ret) {
  77.                 keys_in_subtree[u] = dfs_id;
  78.             }
  79.             return ret;
  80.         };
  81.         vector<int> roots;
  82.         for (const auto &x : start_from) {
  83.             if (seen[x] != dfs_id) {
  84.                 up[x] = 0;
  85.                 find_keys(find_keys, x, -1);
  86.                 roots.push_back(x);
  87.             }
  88.         }
  89.         auto dfs = [&] (auto f, int u, int p) -> pair<int,int> /* length, destination */ {
  90.             vector<pair<int,int>> children;
  91.             for (const auto &x : adj[u].first) {
  92.                 if (x.second != p && keys_in_subtree[x.second] == dfs_id) {
  93.                     pair<int,int> z = f(f, x.second, u);
  94.                     z.first += x.first;
  95.                     children.push_back(z);
  96.                 }
  97.             }
  98.             if (children.size() > 1 || is_key[u] == dfs_id || p == -1 /* root */) {
  99.                 for (const auto &[l, dest] : children) {
  100.                     to_l.push_back({dest, u, tl, tm, l});
  101.                     to_r.push_back({dest, u, tm+1, tr, l});
  102.                 }
  103.                 return {0, u};
  104.             }
  105.             if (children.size()) {
  106.                 return children.front();
  107.             }
  108.             return {0, u};
  109.         };
  110.         for (const auto &x : roots) {
  111.             dfs(dfs, x, -1);
  112.         }
  113.         if (tl == tr) {
  114.             if (tp[tl] != "lca") {
  115.                 return;
  116.             }
  117.             auto [u, v, rt] = ask[tl];
  118.             ans[tl] = 0;
  119.             for (const auto &x : {LCA(u,v), LCA(u, rt), LCA(v, rt)}) {
  120.                 if (x == -1) {
  121.                     ans[tl] = -1;
  122.                     break;
  123.                 }
  124.                 ans[tl] ^= x;
  125.             }
  126.             return;
  127.         }
  128.         f(f, tl, tm, to_l);
  129.         f(f, tm+1, tr, to_r);
  130.     };
  131.     vector<Edge> edges(q+1, {-1,-1,-1,-1,-1});
  132.     for (int ii = 1; ii <= q; ii += 1) {
  133.         cin >> tp[ii];
  134.         if (tp[ii] == "link") {
  135.             cin >> edges[ii].u >> edges[ii].v;
  136.             edges[ii].ql = ii;
  137.             edges[ii].qr = q;
  138.             edges[ii].length = 1;
  139.         }
  140.         if (tp[ii] == "cut") {
  141.             int i;
  142.             cin >> i;
  143.             edges[i].qr = ii-1;
  144.         }
  145.         if (tp[ii] == "lca") {
  146.             auto &[u, v, root] = ask[ii];
  147.             cin >> u >> v >> root;
  148.         }
  149.     }
  150.     {vector<Edge> nw;for(int ii = 1; ii <= q; ii += 1)if(tp[ii] == "link")nw.push_back(edges[ii]);edges = nw;}
  151.     go(go, 1, q, edges);
  152.     for (int i = 1; i <= q; i += 1) {
  153.         if (tp[i] == "lca") {
  154.             cout << ans[i] << "\n";
  155.         }
  156.     }
  157. }
  158.  
Add Comment
Please, Sign In to add comment