prog3r

B

Feb 6th, 2026
71
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.36 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<int> ask(q+1, -888), ans(q+1, -999);
  12.     vector<pair<int,int>> seen(n+1); // {dfs_id, start_id}
  13.     vector<int> is_key(n+1); // {dfs_id}
  14.     vector<int> keys_in_subtree(n+1); // {dfs_id}
  15.     vector<pair<Edge,int>> up(n+1); // {edge, dfs_id}
  16.     vector<pair<vector<Edge>,int>> down(n+1); // {edges, dfs_id}
  17.     int dfs_id = 0;
  18.     auto go = [&] (auto f, int tl, int tr, vector<Edge> edges) -> void {
  19.         dfs_id += 1;
  20.         int tm = (tl + tr) >> 1;
  21.         for (int i = tl; i <= tr; i += 1) {
  22.             is_key[ask[i]] = dfs_id;
  23.         }
  24.         vector<int> start_from;
  25.         vector<Edge> to_l, to_r;
  26.         for (const auto &[u, v, l, r, length] : edges) {
  27.             if (l<=tl&&tr<=r) {
  28.                 up[u] = {{u,v,l,r,length}, dfs_id};
  29.                 start_from.push_back(u);
  30.                 if (down[v].second != dfs_id) {
  31.                     down[v].second = dfs_id;
  32.                     down[v].first.clear();
  33.                 }
  34.                 if (down[u].second != dfs_id) {
  35.                     down[u].second = dfs_id;
  36.                     down[u].first.clear();
  37.                 }
  38.                 down[v].first.push_back({u,v,l,r,length});
  39.             } else {
  40.                 is_key[u] = dfs_id;
  41.                 is_key[v] = dfs_id;
  42.                 if (l <= tm) {
  43.                     to_l.push_back({u,v,l,min(r,tm),length});
  44.                 }
  45.                 if (r >= tm+1) {
  46.                     to_r.push_back({u,v,max(l, tm+1),r,length});
  47.                 }
  48.             }
  49.         }
  50.         vector<int> roots;
  51.         for (const auto &x : start_from) {
  52.             int y = x;
  53.             if (seen[y].first == dfs_id) {
  54.                 continue;
  55.             }
  56.             while (true) {
  57.                 seen[y] = {dfs_id, x};
  58.                 if (up[y].second != dfs_id || seen[up[y].first.v] == seen[y]) {
  59.                     roots.push_back(y);
  60.                     break;
  61.                 }
  62.                 if (seen[up[y].first.v].first == dfs_id) {
  63.                     break;
  64.                 }
  65.                 y = up[y].first.v;
  66.             }
  67.         }
  68.         auto find_keys = [&] (auto f, int u, int rt) -> bool {
  69.             bool ret = is_key[u] == dfs_id;
  70.             for (const auto &x : down[u].first) {
  71.                 if (x.u != rt) {
  72.                     ret |= f(f, x.u, rt);
  73.                 }
  74.             }
  75.             if (ret) {
  76.                 keys_in_subtree[u] = dfs_id;
  77.             }
  78.             return ret;
  79.         };
  80.         for (const auto &x : roots) {
  81.             find_keys(find_keys, x, x);
  82.         }
  83.         for (const auto &x : roots) {
  84.             if (keys_in_subtree[x] == dfs_id && up[x].second == dfs_id) {
  85.                 is_key[up[x].first.v] = dfs_id; // asking not to skip this node
  86.             }
  87.         }
  88.         for (const auto &x : roots) {
  89.             find_keys(find_keys, x, x);
  90.         }
  91.         auto dfs = [&] (auto f, int u, int rt) -> pair<int,int> /* length, destination */ {
  92.             vector<pair<int,int>> children;
  93.             for (const auto &x : down[u].first) {
  94.                 if (x.u != rt && keys_in_subtree[x.u] == dfs_id) {
  95.                     pair<int,int> z = f(f, x.u, rt);
  96.                     z.first += x.length;
  97.                     children.push_back(z);
  98.                 }
  99.             }
  100.             if (children.size() > 1 || is_key[u] == dfs_id || u == rt) {
  101.                 for (const auto &[l, dest] : children) {
  102.                     to_l.push_back({dest, u, tl, tm, l});
  103.                     to_r.push_back({dest, u, tm+1, tr, l});
  104.                 }
  105.                 return {0, u};
  106.             }
  107.             if (children.size()) {
  108.                 return children.front();
  109.             }
  110.             return {0, u};
  111.         };
  112.         for (const auto &x : roots) {
  113.             if (keys_in_subtree[x] == dfs_id) {
  114.                 dfs(dfs, x, x);
  115.                 if (up[x].second == dfs_id) {
  116.                     to_l.push_back({x, up[x].first.v, tl, tm, up[x].first.length});
  117.                     to_r.push_back({x, up[x].first.v, tm+1, tr, up[x].first.length});
  118.                 }
  119.             }
  120.         }
  121.         if (tl == tr) {
  122.             int y = ask[tl];
  123.             ans[tl] = 0;
  124.             dfs_id += 1;
  125.             while (seen[y].first != dfs_id) {
  126.                 seen[y].first = dfs_id;
  127.                 ans[tl] += up[y].first.length;
  128.                 y = up[y].first.v;
  129.             }
  130.             return;
  131.         }
  132.         f(f, tl, tm, to_l);
  133.         f(f, tm+1, tr, to_r);
  134.     };
  135.     vector<int> added_at_time(n+1, 1);
  136.     vector<int> edge_to(n+1);
  137.     iota(edge_to.begin(), edge_to.end(), 0ll);
  138.     vector<Edge> edges;
  139.     for (int i = 1; i <= q; i += 1) {
  140.         int pos, val;
  141.         cin >> pos >> val >> ask[i];
  142.         if (added_at_time[pos] <= i-1) {
  143.             edges.push_back({pos, edge_to[pos], added_at_time[pos], i-1, 1});
  144.         }
  145.         edge_to[pos] = val;
  146.         added_at_time[pos] = i;
  147.     }
  148.     for (int pos = 1; pos <= n; pos += 1) {
  149.         edges.push_back({pos, edge_to[pos], added_at_time[pos], q, 1});
  150.     }
  151.     go(go, 1, q, edges);
  152.     for (int i = 1; i <= q; i += 1) {
  153.         cout << ans[i] << "\n";
  154.     }
  155. }
  156.  
Add Comment
Please, Sign In to add comment