mr_dot_convict

TALCA-codechef-mr.convict

Oct 6th, 2019
102
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.36 KB | None | 0 0
  1. // Hack it and have it ;) //
  2. /*author* Priyanshu Shrivastav (from IIT Palakkad) *
  3.  * *_ __ ___  _ ______ ___  _ ____   ___  ___| |_  *
  4.  * | '_ ` _ \| '__/ __/ _ \| '_ \ \ / / |/ __| __| *
  5.  * | | | | | | | | (_| (_) | | | \ V /| | (__| |_  *
  6.  * |_| |_| |_|_|(_)___\___/|_| |_|\_/ |_|\___|\__| *
  7. When I wrote this, only God and I understood what I was doing
  8.  ** * * * * * * * Now, only God knows!* * * * * * */
  9. #include      <bits/stdc++.h>
  10. #include      <ext/pb_ds/assoc_container.hpp>
  11. #include      <ext/pb_ds/tree_policy.hpp>
  12. using namespace std;
  13. using namespace __gnu_pbds;
  14.  
  15. #ifndef CONVICTION
  16. #pragma GCC       optimize ("Ofast")
  17. #pragma GCC       optimize ("unroll-loops")
  18. #pragma GCC       target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
  19. #endif
  20.  
  21. #define IOS       ios_base::sync_with_stdio(false); cin.tie (nullptr)
  22. #define PREC      cout.precision (10); cout << fixed
  23. #define x         first
  24. #define y         second
  25. #define fr(i,x,y) for (int i = x; i <= y; ++i)
  26. #define fR(i,x,y) for (int i = x; i >= y; --i)
  27. #define bg(x)     " [ " << #x << " : " << (x) << " ] "
  28. #define un(x)     sort(x.begin(), x.end()), \
  29.                   x.erase(unique(x.begin(), x.end()), x.end())
  30.  
  31. using   ll  =     long long;
  32. using   ull =     unsigned long long;
  33. using   ff  =     long double;
  34. using   pii =     pair<int,int>;
  35. using   pil =     pair<int,ll>;
  36. typedef tree
  37. < int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update>
  38. ordered_set;
  39.  
  40. struct chash {
  41.    int operator () (pii x) const { return x.x*31 + x.y; }
  42. };
  43. gp_hash_table <pii, int, chash> mp;
  44.  
  45. #if __cplusplus > 201103L
  46. seed_seq seq{
  47.    (uint64_t) chrono::duration_cast<chrono::nanoseconds>
  48.       (chrono::high_resolution_clock::now().time_since_epoch()).count(),
  49.       (uint64_t) __builtin_ia32_rdtsc(),
  50.       (uint64_t) (uintptr_t) make_unique<char>().get()
  51. };
  52. mt19937 rng(seq); //uniform_int_distribution<int> (l, h)(rng); //[low, high]
  53. #else
  54. auto seed = chrono::high_resolution_clock::now().time_since_epoch().count();
  55. mt19937 rng(seed);
  56. #endif
  57.  
  58. #define debug(args...) { \
  59.    /* WARNING : do NOT compile this debug func calls with following flags: // \
  60.     * // -D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC -D_FORTIFY_SOURCE=2*/ \
  61.    string _s = #args; replace(_s.begin(), _s.end(), ',', ' ');\
  62.    stringstream _ss(_s); \
  63.    istream_iterator<string> _it(_ss); err(_it, args); \
  64. }
  65. void err(istream_iterator<string> it) {
  66.    it->empty(); cerr << " (Line : " << __LINE__ << ")" << '\n';
  67. }
  68. template<typename T, typename... Args>
  69. void err(istream_iterator<string> it, T a, Args... args) {
  70.    cerr << fixed << setprecision(15)
  71.       << " [ " <<  *it << " : " << a  << " ] "<< ' ';
  72.    err(++it, args...);
  73. }
  74. /*****************************************************************************/
  75. //Don’t practice until you get it right. Practice until you can’t get it wrong
  76.  
  77. class LCA {
  78.    public:
  79.    int V;
  80.    const int D = 21; // for handling n upto 2e6
  81.    vector <vector <int>> table, dp;
  82.    vector <int> depth;
  83.  
  84.    inline int walk(int u, int k) {
  85.       for (int d = 0; d <= D && u != -1; ++d) {
  86.          if ((1 << d) & k) {
  87.             u = table[u][d];
  88.          }
  89.       }
  90.       return u;
  91.    }
  92.  
  93.    LCA(int n, vector <vector<pair <int, int>>> &T, int root = 0) {
  94.       V = n;
  95.       table.assign(n, vector <int>(D + 1, -1));
  96.       dp.assign(n, vector <int>(D + 1, INT_MAX));
  97.       depth.assign(n, 0);
  98.  
  99.       function <void(int, int, int)> dfs =
  100.          [&](int u, int pr, int d) -> void {
  101.             depth[u] = d;
  102.             for (auto v_pair : T[u]) {
  103.                int v = v_pair.first;
  104.                int w = v_pair.second;
  105.                if (v == pr) continue;
  106.                table[v][0] = u;
  107.                dp[v][0] = w;
  108.                dfs(v, u, d + 1);
  109.             }
  110.          };
  111.  
  112.       dfs(root, -1, 0);
  113.  
  114.       for (int k = 1; k <= D; ++k) {
  115.          for (int i = 0; i < n; ++i) {
  116.             if (table[i][k - 1] == -1) continue;
  117.             table[i][k] = table[table[i][k - 1]][k - 1];
  118.             dp[i][k] = min(dp[i][k - 1], dp[table[i][k - 1]][k - 1]);
  119.          }
  120.       }
  121.    }
  122.  
  123.    int find_lca(int u, int v) {
  124.       if (depth[u] > depth[v]) {
  125.          u = walk(u, depth[u] - depth[v]);
  126.       }
  127.       else if (depth[u] < depth[v]) {
  128.          v = walk(v, depth[v] - depth[u]);
  129.       }
  130.       if (u == v) return u;
  131.  
  132.       for (int d = D; d >= 0; --d) {
  133.          if (table[u][d] != table[v][d]) {
  134.             u = table[u][d];
  135.             v = table[v][d];
  136.          }
  137.       }
  138.       return table[u][0];
  139.    }
  140. };
  141.  
  142. signed main() {
  143.    IOS; PREC;
  144.  
  145.    int n;
  146.    cin >> n;
  147.    vector <vector<pii>> T(n, vector <pii>());
  148.    for (int i = 0; i < n - 1; ++i) {
  149.       int u, v; cin >> u >> v;
  150.       --u, --v;
  151.       T[u].push_back(make_pair(v, 1));
  152.       T[v].push_back(make_pair(u, 1));
  153.    }
  154.  
  155.    LCA solve(n, T);
  156.  
  157.    int q; cin >> q;
  158.    while (q--){
  159.       int r, x, y;
  160.       cin >> r >> x >> y;
  161.       --r, --x, --y;
  162.       int z = solve.find_lca(x, y);
  163.  
  164.       int zr, xr, yr;
  165.       zr = solve.find_lca(z, r);
  166.       xr = solve.find_lca(x, r);
  167.       yr = solve.find_lca(y, r);
  168.  
  169.       if (zr != z || (xr == z && yr == z)) {
  170.          cout << z + 1 << '\n';
  171.       }
  172.       else {
  173.          if (yr == z) cout << xr + 1 << '\n';
  174.          else if (xr == z) cout << yr + 1 << '\n';
  175.          else assert(false);
  176.       }
  177.    }
  178.  
  179.    return EXIT_SUCCESS;
  180. }
Add Comment
Please, Sign In to add comment