Advertisement
tien_noob

BOI19 - upgraded

May 4th, 2022
607
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.10 KB | None | 0 0
  1. //Make CSP great again
  2. //Vengeance
  3. #include <bits/stdc++.h>
  4. #define TASK "TESTCODE"
  5. #define Log2(x) 31 - __builtin_clz(x)
  6. using namespace std;
  7. const int N = 1e5 , cbit = 16;
  8. int f[N + 1][cbit + 1], depth[N + 1], l[N + 1], r[N + 1], w[N + 1], sz[N + 1], par[N + 1], timer, n, s, q, e;
  9. long long g[N + 1];
  10. bool visited[N + 1];
  11. set<pair<long long, int> > dp[N + 1];
  12. vector<int> adj[N + 1];
  13. void read()
  14. {
  15.     cin >> n >> s >> q >> e;
  16.     for (int i = 1; i < n; ++ i)
  17.     {
  18.         cin >> l[i] >> r[i] >> w[i];
  19.         adj[l[i]].push_back(i);
  20.         adj[r[i]].push_back(i);
  21.     }
  22. }
  23. void DFS(int u, int p)
  24. {
  25.     for (int x: adj[u])
  26.     {
  27.         int v = l[x] ^ r[x] ^ u;
  28.         if (v == p)
  29.         {
  30.             continue;
  31.         }
  32.         depth[v] = depth[u] + 1;
  33.         g[v] = g[u] + w[x];
  34.         f[v][0] = u;
  35.         for (int i = 1; i <= cbit; ++ i)
  36.         {
  37.             f[v][i] = f[f[v][i - 1]][i - 1];
  38.         }
  39.         DFS(v, u);
  40.     }
  41. }
  42. int LCA(int u, int v)
  43. {
  44.     if (depth[v] < depth[u])
  45.     {
  46.         swap(u, v);
  47.     }
  48.     int k = depth[v] - depth[u];
  49.     for (int i = cbit; i >= 0; -- i)
  50.     {
  51.         if ((k >> i) & 1)
  52.         {
  53.             v = f[v][i];
  54.         }
  55.     }
  56.     if (u == v)
  57.     {
  58.         return u;
  59.     }
  60.     for (int i = cbit; i >= 0; -- i)
  61.     {
  62.         if (f[u][i] != f[v][i])
  63.         {
  64.             u = f[u][i];
  65.             v = f[v][i];
  66.         }
  67.     }
  68.     return f[u][0];
  69. }
  70. long long dis(int u, int v)
  71. {
  72.     int k = LCA(u, v);
  73.     return g[u] + g[v] - 2 * g[k];
  74. }
  75. void CenDFS(int u, int p)
  76. {
  77.     sz[u] = 1;
  78.     for (int x : adj[u])
  79.     {
  80.         int v = l[x] ^ r[x] ^ u;
  81.         if (v == p || visited[v])
  82.         {
  83.             continue;
  84.         }
  85.         CenDFS(v, u);
  86.         sz[u] += sz[v];
  87.     }
  88. }
  89. int FindCentroid(int u, int p, int s)
  90. {
  91.     for (int x : adj[u])
  92.     {
  93.         int v = l[x] ^ r[x] ^ u;
  94.         if (v == p || visited[v])
  95.         {
  96.             continue;
  97.         }
  98.         if (sz[v] > s/2)
  99.         {
  100.             return FindCentroid(v, u, s);
  101.         }
  102.     }
  103.     return u;
  104. }
  105. int BuildCentroid(int u)
  106. {
  107.     CenDFS(u, 0);
  108.     int root = FindCentroid(u, 0, sz[u]);
  109.     visited[root] = true;
  110.     for (int x : adj[root])
  111.     {
  112.         int v = l[x] ^ r[x] ^ root;
  113.         if (visited[v])
  114.         {
  115.             continue;
  116.         }
  117.         par[BuildCentroid(v)] = root;
  118.     }
  119.     return root;
  120. }
  121. void update(int u)
  122. {
  123.     for (int v = u; v > 0; v = par[v])
  124.     {
  125.         dp[v].insert({dis(u, v), u});
  126.     }
  127. }
  128. int nchain = 1, chain[N + 1], pos[N + 1], head[N + 1];
  129. void preHLD(int u, int p)
  130. {
  131.     sz[u] = 1;
  132.     for (int x : adj[u])
  133.     {
  134.         int v = l[x] ^ r[x] ^ u;
  135.         if (v == p)
  136.         {
  137.             continue;
  138.         }
  139.         preHLD(v, u);
  140.         sz[u] += sz[v];
  141.     }
  142. }
  143. struct FenwickTree
  144. {
  145.     int tree[N + 1];
  146.     void add(int pos, int val)
  147.     {
  148.         for (; pos <= n; pos += (pos & (-pos)))
  149.         {
  150.             tree[pos] += val;
  151.         }
  152.     }
  153.     int sum(int pos)
  154.     {
  155.         int ret = 0;
  156.         for (; pos > 0; pos -= (pos & (-pos)))
  157.         {
  158.             ret += tree[pos];
  159.         }
  160.         return ret;
  161.     }
  162.     int sum(int l, int r)
  163.     {
  164.         if (l > r)
  165.         {
  166.             return 0;
  167.         }
  168.         return sum(r) - sum(l - 1);
  169.     }
  170. } tree;
  171. void HLD(int u, int p)
  172. {
  173.     int bigchild = -1;
  174.     chain[u] = nchain;
  175.     pos[u] = ++timer;
  176.     if (head[nchain] == 0)
  177.     {
  178.         head[nchain] = u;
  179.     }
  180.     for (int x : adj[u])
  181.     {
  182.         int v = l[x] ^ r[x] ^ u;
  183.         if (v == p)
  184.         {
  185.             continue;
  186.         }
  187.         if (bigchild == -1 || sz[bigchild] < sz[v])
  188.         {
  189.             bigchild = v;
  190.         }
  191.     }
  192.     if (bigchild != -1)
  193.     {
  194.         HLD(bigchild, u);
  195.     }
  196.     for (int x : adj[u])
  197.     {
  198.         int v = l[x] ^ r[x] ^ u;
  199.         if (v == bigchild || v == p)
  200.         {
  201.             continue;
  202.         }
  203.         ++nchain;
  204.         HLD(v, u);
  205.     }
  206. }
  207. bool reachable(int u, int p)
  208. {
  209.     while(chain[u] != chain[p])
  210.     {
  211.         if (tree.sum(pos[head[chain[u]]], pos[u]) > 0)
  212.         {
  213.             return false;
  214.         }
  215.         u = f[head[chain[u]]][0];
  216.     }
  217.     return tree.sum(pos[p] + 1, pos[u]) == 0;
  218. }
  219. bool reach(int u, int v)
  220. {
  221.     int k = LCA(u, v);
  222.     return reachable(u, k) && reachable(v, k);
  223. }
  224. int get(int u)
  225. {
  226.     long long res = -1;
  227.     for (int v = u; v > 0; v = par[v])
  228.     {
  229.         while(!dp[v].empty() && !reach(dp[v].begin()->second, v))
  230.         {
  231.             dp[v].erase(dp[v].begin());
  232.         }
  233.         if (reach(u, v) && !dp[v].empty())
  234.         {
  235.             if (res == -1 || res > dp[v].begin()->first + dis(u, v))
  236.             {
  237.                 res = dp[v].begin()->first + dis(u, v);
  238.             }
  239.         }
  240.     }
  241.     return res;
  242. }
  243. void prepare()
  244. {
  245.     DFS(1, 0);
  246.     par[BuildCentroid(1)] = 0;
  247.     timer = 0;
  248.     preHLD(1, 0);
  249.     HLD(1, 0);
  250.     for (int i = 1; i <= s; ++ i)
  251.     {
  252.         int u;
  253.         cin >> u;
  254.         update(u);
  255.     }
  256.     fill(visited + 1, visited + n, false);
  257. }
  258. void solve()
  259. {
  260.     prepare();
  261.     while(q--)
  262.     {
  263.         int i, u;
  264.         cin >> i >> u;
  265.         if (!visited[i])
  266.         {
  267.             visited[i] = true;
  268.             if (depth[l[i]] > depth[r[i]])
  269.             {
  270.                 swap(l[i], r[i]);
  271.             }
  272.             tree.add(pos[r[i]], 1);
  273.         }
  274.         if (reach(u, e))
  275.         {
  276.             cout << "escaped" << '\n';
  277.             continue;
  278.         }
  279.         long long res = get(u);
  280.         if (res == -1)
  281.         {
  282.             cout << "oo" << '\n';
  283.         }
  284.         else
  285.         {
  286.             cout << res << '\n';
  287.         }
  288.     }
  289. }
  290. int main()
  291. {
  292.     ios_base::sync_with_stdio(false);
  293.     cin.tie(nullptr);
  294.     if (fopen(TASK".INP", "r"))
  295.     {
  296.         freopen(TASK".INP", "r", stdin);
  297.         //freopen(TASK".OUT", "w", stdout);
  298.     }
  299.     int t = 1;
  300.     bool typetest = false;
  301.     if (typetest)
  302.     {
  303.         cin >> t;
  304.     }
  305.     for (int __ = 1; __ <= t; ++ __)
  306.     {
  307.         //cout << "Case " << __ << ": ";
  308.         read();
  309.         solve();
  310.     }
  311. }
  312.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement