arujbansal

Untitled

Apr 14th, 2021 (edited)
125
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.15 KB | None | 0 0
  1. #include <iostream>
  2. #include <algorithm>
  3. #include <vector>
  4. #include <map>
  5. #include <set>
  6. #include <array>
  7. #include <stack>
  8. #include <queue>
  9. #include <random>
  10. #include <numeric>
  11. #include <functional>
  12. #include <chrono>
  13. #include <utility>
  14. #include <iomanip>
  15. #include <assert.h>
  16.  
  17. using namespace std;
  18.  
  19. void dbg_out() { cerr << endl; }
  20. template<typename Head, typename... Tail>
  21. void dbg_out(Head H, Tail... T) { cerr << ' ' << H; dbg_out(T...); }
  22. #define dbg(...) cerr << "(" << #__VA_ARGS__ << "):", dbg_out(__VA_ARGS__)
  23.  
  24. #define rng_init mt19937 rng(chrono::steady_clock::now().time_since_epoch().count())
  25. #define rng_seed(x) mt19937 rng(x)
  26. #define all(x) (x).begin(), (x).end()
  27. #define sz(x) (int) (x).size()
  28. // #define int long long
  29.  
  30. const int MXN = 1e5 + 5, INF = 1e9 + 5;
  31. int N, Q, node;
  32. vector<pair<char, int>> queries;
  33. vector<int> g[MXN];
  34. vector<pair<int, int>> par[MXN];
  35. int subtree[MXN];
  36. bool vis[MXN];
  37.  
  38. struct two_set {
  39.     pair<int, int> x = {-INF, -1}, y = {-INF, -1};
  40.  
  41.     void insert(int dist, int id) {
  42.         pair<int, int> z = make_pair(dist, id);
  43.  
  44.         if (x.second == id) x = max(y, z);
  45.         else  y = max(y, z);
  46.  
  47.         if (x.first < y.first) swap(x, y);
  48.     }
  49.  
  50.     int query(int id) {
  51.         return (x.second == id ? y.first : x.first);
  52.     }
  53. };
  54.  
  55. two_set best[MXN];
  56.  
  57. void calc_subtree(int u, int p) {
  58.     subtree[u] = 1;
  59.  
  60.     for (const auto &v : g[u]) {
  61.         if (v == p) continue;
  62.         calc_subtree(v, u);
  63.         subtree[u] += subtree[v];
  64.     }
  65. }
  66.  
  67. int find_centroid(int u, int p, int vertices) {
  68.     if (p != -1) {
  69.         subtree[p] -= subtree[u];
  70.         subtree[u] += subtree[p];
  71.     }
  72.  
  73.     for (const auto &v : g[u]) {
  74.         if (v == p || vis[v]) continue;
  75.  
  76.         if (subtree[v] * 2 > vertices)
  77.             return find_centroid(v, u, vertices);
  78.     }
  79.  
  80.     return u;
  81. }
  82.  
  83. void dfs(int u, int p, int dist, int centroid) {
  84.     par[u].emplace_back(centroid, dist);
  85.  
  86.     for (const auto &v : g[u]) {
  87.         if (v == p || vis[v]) continue;
  88.         dfs(v, u, dist + 1, centroid);
  89.     }
  90. }
  91.  
  92. void build_tree(int u) {
  93.     int centroid = find_centroid(u, -1, subtree[u]);
  94.     vis[centroid] = true;
  95.  
  96.     for (const auto &v : g[centroid]) {
  97.         if (vis[v]) continue;
  98.         dfs(v, centroid, 1, centroid);
  99.     }
  100.  
  101.     for (const auto &v : g[centroid]) {
  102.         if (vis[v]) continue;
  103.         build_tree(v);
  104.     }
  105. }
  106.  
  107. void add_node(int v) {
  108.     best[v].insert(0, v);
  109.  
  110.     int child = v;
  111.     for (const auto &[centroid, dist] : par[v]) {
  112.         best[centroid].insert(dist, child);
  113.         child = centroid;
  114.     }
  115. }
  116.  
  117. int query(int v) {
  118.     int ans = best[v].x.first, child = v;
  119.  
  120.     for (const auto &[centroid, dist] : par[v]) {
  121.         ans = max(ans, dist + best[centroid].query(child));
  122.         child = centroid;
  123.     }
  124.  
  125.     return ans;
  126. }
  127.  
  128. void solve() {
  129.     cin >> Q;  
  130.  
  131.     for (int i = 0; i < Q; i++) {
  132.         char type;
  133.         int x;
  134.         cin >> type >> x;
  135.         x--;
  136.  
  137.         queries.emplace_back(type, x);
  138.  
  139.         if (type == 'B') {
  140.             if (x < 0) {
  141.                 N++;
  142.                 continue;
  143.             }
  144.  
  145.             g[N].push_back(x);
  146.             g[x].push_back(N);
  147.  
  148.             N++;
  149.         }
  150.     }
  151.  
  152.     for (int i = 0; i < N; i++) {
  153.         if (vis[i]) continue;
  154.  
  155.         calc_subtree(i, -1);
  156.         build_tree(i);
  157.     }
  158.    
  159.     for (int i = 0; i < N; i++)
  160.         reverse(all(par[i]));
  161.  
  162.     vector<bool> built(N, false);
  163.  
  164.     for (const auto &[type, v] : queries) {
  165.         if (type == 'B') {
  166.             if (v < 0) {
  167.                 node++;
  168.                 continue;
  169.             }
  170.  
  171.             if (!built[v]) {
  172.                 add_node(v);
  173.                 built[v] = true;
  174.             }
  175.  
  176.             add_node(node);
  177.             built[node++] = true;
  178.         } else {
  179.             cout << (built[v] ? max(0, query(v)) : 0) << "\n";
  180.         }
  181.     }
  182. }
  183.  
  184. signed main() {
  185.     ios_base::sync_with_stdio(false);
  186.     cin.tie(nullptr);
  187.  
  188. #ifndef local
  189.     freopen("newbarn.in", "r", stdin);
  190.     freopen("newbarn.out", "w", stdout);
  191. #endif
  192.  
  193.     int TC = 1;
  194.     // cin >> TC;
  195.     while (TC--) solve();
  196. }
Add Comment
Please, Sign In to add comment