prog3r

D1

Feb 6th, 2026
94
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.73 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. #define int long long
  4. constexpr int INF = 1e18;
  5. signed main() {
  6.     ios::sync_with_stdio(0);
  7.     cin.tie(0);
  8.     struct Edge {
  9.         int u, v, ql, qr, length;
  10.     };
  11.     struct Vertex {
  12.         int u, ql, qr, color;
  13.     };
  14.     struct VertexValues /* These values are shared across whole segment (t=l..r), these values get relaxed in different segtree nodes */ {
  15.         int u, dist_to_blue, dist_to_red;
  16.     };
  17.     int n, q;
  18.     cin >> n >> q;
  19.     vector<int> ask(q+1, -888);
  20.     vector<string> tp(q+1);
  21.     vector<int> ans(q+1, -999);
  22.     vector<int> seen(n+1); // {dfs_id}
  23.     vector<int> is_key(n+1); // {dfs_id}
  24.     vector<int> keys_in_subtree(n+1); // {dfs_id}
  25.     vector<pair<int,int>> vvs(n+1); // {dist_to_blue, dist_to_red}
  26.     vector<pair<vector<pair<int,int>>,int>> adj(n+1); // {{length,to}, dfs_id}
  27.     int dfs_id = 0;
  28.     auto go = [&] (auto f, int tl, int tr, tuple<vector<Edge>,vector<Vertex>,vector<VertexValues>> G) -> void {
  29.         dfs_id += 1;
  30.         int tm = (tl + tr) >> 1;
  31.         for (int i = tl; i <= tr; i += 1) {
  32.             if (tp[i] == "link" || tp[i] == "cut") {
  33.                 continue;
  34.             }
  35.             is_key[ask[i]] = dfs_id;
  36.         }
  37.         vector<Edge> etol, etor;
  38.         vector<int> start_from;
  39.         for (const auto &[u, v, l, r, length] : get<0>(G)) {
  40.             if (l<=tl&&tr<=r) {
  41.                 start_from.push_back(u), start_from.push_back(v);
  42.                 vvs[u] = vvs[v] = {(int)INF, (int)INF};
  43.                 if (adj[u].second != dfs_id) {
  44.                     adj[u].second = dfs_id;
  45.                     adj[u].first.clear();
  46.                 }adj[u].first.push_back({length, v});
  47.                 if (adj[v].second != dfs_id) {
  48.                     adj[v].second = dfs_id;
  49.                     adj[v].first.clear();
  50.                 }adj[v].first.push_back({length, u});
  51.             } else {
  52.                 is_key[u] = dfs_id;
  53.                 is_key[v] = dfs_id;
  54.                 if (l <= tm) {
  55.                     etol.push_back({u,v,l,min(r,tm),length});
  56.                 }
  57.                 if (r >= tm+1) {
  58.                     etor.push_back({u,v,max(l, tm+1),r,length});
  59.                 }
  60.             }
  61.         }
  62.         for (const auto &[u, b, r] : get<2>(G)) {
  63.             vvs[u] = {b, r};
  64.         }
  65.         for (const auto &[u, l, r, co] : get<1>(G)) {
  66.             if (l<=tl&&tr<=r) {
  67.                 if (co == 0) {
  68.                     vvs[u].first = min(vvs[u].first, 0ll);
  69.                 }
  70.                 if (co == 1) {
  71.                     vvs[u].second = min(vvs[u].second, 0ll);
  72.                 }
  73.             } else {
  74.                 is_key[u] = dfs_id;
  75.             }
  76.         }
  77.         vector<Vertex> vtol, vtor;
  78.         for (const auto &[u, l, r, co] : get<1>(G)) {
  79.             if (is_key[u] == dfs_id) {
  80.                 if (l <= tm) {
  81.                     vtol.push_back({u,l,min(r,tm),co});
  82.                 }
  83.                 if (r >= tm+1) {
  84.                     vtor.push_back({u,max(l, tm+1),r,co});
  85.                 }
  86.             }
  87.         }
  88.         vector<vector<tuple<int,int,int>>> dfs_tree_layers(start_from.size());
  89.         auto find_keys = [&] (auto f, int u, int p, int l) -> bool {
  90.             seen[u] = dfs_id;
  91.             bool ret = is_key[u] == dfs_id;
  92.             for (const auto &x : adj[u].first) {
  93.                 if (x.second != p) {
  94.                     dfs_tree_layers[l].push_back({x.first, u, x.second});
  95.                     ret |= f(f, x.second, u, l+1);
  96.                 }
  97.             }
  98.             if (ret) {
  99.                 keys_in_subtree[u] = dfs_id;
  100.             }
  101.             return ret;
  102.         };
  103.         vector<int> roots;
  104.         for (const auto &x : start_from) {
  105.             if (seen[x] != dfs_id) {
  106.                 find_keys(find_keys, x, -1, 0);
  107.                 roots.push_back(x);
  108.             }
  109.         }
  110.         vector<tuple<int,int,int>> layers_order;
  111.         for (const auto &x : dfs_tree_layers) {
  112.             for (const auto &y : x) {
  113.                 layers_order.push_back(y);
  114.             }
  115.         }
  116.         for (int i = 0; i < 2; i += 1) {
  117.             reverse(layers_order.begin(), layers_order.end());
  118.             for (auto &[l, from, to] : layers_order) {
  119.                 swap(from, to);
  120.             }
  121.             for (const auto &[l, from, to] : layers_order) {
  122.                 vvs[to].first = min(vvs[to].first, vvs[from].first+l);
  123.                 vvs[to].second = min(vvs[to].second, vvs[from].second+l);
  124.             }
  125.         }
  126.         auto dfs = [&] (auto f, int u, int p) -> pair<int,int> /* length, destination */ {
  127.             vector<pair<int,int>> children;
  128.             for (const auto &x : adj[u].first) {
  129.                 if (x.second != p && keys_in_subtree[x.second] == dfs_id) {
  130.                     pair<int,int> z = f(f, x.second, u);
  131.                     z.first += x.first;
  132.                     children.push_back(z);
  133.                 }
  134.             }
  135.             if (children.size() > 1 || is_key[u] == dfs_id || p == -1 /* root */) {
  136.                 for (const auto &[l, dest] : children) {
  137.                     etol.push_back({dest, u, tl, tm, l});
  138.                     etor.push_back({dest, u, tm+1, tr, l});
  139.                 }
  140.                 return {0, u};
  141.             }
  142.             if (children.size()) {
  143.                 return children.front();
  144.             }
  145.             return {0, u};
  146.         };
  147.         for (const auto &x : roots) {
  148.             dfs(dfs, x, -1);
  149.         }
  150.         if (tl == tr) {
  151.             if (tp[tl] == "get_blue") {
  152.                 ans[tl] = vvs[ask[tl]].first == INF ? -1 : vvs[ask[tl]].first;
  153.             }
  154.             if (tp[tl] == "get_red") {
  155.                 ans[tl] = vvs[ask[tl]].second == INF ? -1 : vvs[ask[tl]].second;
  156.             }
  157.             return;
  158.         }
  159.         vector<VertexValues> vvs_pass_down;
  160.         for (const auto &[u, l, r, co] : get<1>(G)) {
  161.             if (is_key[u] == dfs_id) {
  162.                 vvs_pass_down.push_back({u, vvs[u].first, vvs[u].second});
  163.             }
  164.         }
  165.         f(f, tl, tm, {etol, vtol, vvs_pass_down});
  166.         f(f, tm+1, tr, {etor, vtor, vvs_pass_down});
  167.     };
  168.     vector<Edge> edges(q+1, {-1,-1,-1,-1,-1});
  169.     vector<Vertex> vertices;
  170.     vector<int> last(n+1); for (int i = 1; i <= n; i += 1) last[i] = i-1, vertices.push_back({i, 1, q, 0});
  171.     for (int ii = 1; ii <= q; ii += 1) {
  172.         cin >> tp[ii];
  173.         if (tp[ii] == "link") {
  174.             cin >> edges[ii].u >> edges[ii].v >> edges[ii].length;
  175.             edges[ii].ql = ii;
  176.             edges[ii].qr = q;
  177.         }
  178.         if (tp[ii] == "cut") {
  179.             int i;
  180.             cin >> i;
  181.             edges[i].qr = ii-1;
  182.         }
  183.         if (tp[ii] == "make_blue") {
  184.             cin >> ask[ii];
  185.             if (last[ask[ii]] != -1) {
  186.                 vertices[last[ask[ii]]].qr = ii-1;
  187.             }last[ask[ii]] = vertices.size(); vertices.push_back({ask[ii], ii, q, 0});
  188.         }
  189.         if (tp[ii] == "make_red") {
  190.             cin >> ask[ii];
  191.             if (last[ask[ii]] != -1) {
  192.                 vertices[last[ask[ii]]].qr = ii-1;
  193.             }last[ask[ii]] = vertices.size(); vertices.push_back({ask[ii], ii, q, 1});
  194.         }
  195.         if (tp[ii] == "get_blue") {
  196.             cin >> ask[ii];
  197.         }
  198.         if (tp[ii] == "get_red") {
  199.             cin >> ask[ii];
  200.         }
  201.     }
  202.     {vector<Edge> nw;for(int ii = 1; ii <= q; ii += 1)if(tp[ii] == "link")nw.push_back(edges[ii]);edges = nw;}
  203.     vector<VertexValues> vv; for (int i = 1; i <= n; i += 1) vv.push_back({i, INF, INF});
  204.     go(go, 1, q, {edges, vertices, vv});
  205.     for (int i = 1; i <= q; i += 1) {
  206.         if (tp[i] == "get_red" || tp[i] == "get_blue") {
  207.             cout << ans[i] << "\n";
  208.         }
  209.     }
  210. }
  211.  
Add Comment
Please, Sign In to add comment