mr_dot_convict

893-F-Subtree-minimum-query-codeforces-mr.convict

May 5th, 2020
147
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.33 KB | None | 0 0
  1. #include      <bits/stdc++.h> /*{{{*/
  2. #include      <ext/pb_ds/assoc_container.hpp>
  3. #include      <ext/pb_ds/tree_policy.hpp>
  4. using namespace std;
  5. using namespace __gnu_pbds;
  6.  
  7. #ifndef CONVICTION
  8. #pragma GCC       optimize ("Ofast")
  9. #pragma GCC       optimize ("unroll-loops")
  10. #pragma GCC       target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
  11. #endif
  12.  
  13. #define IOS       ios_base::sync_with_stdio(false); cin.tie (nullptr)
  14. #define PREC      cout.precision (10); cout << fixed
  15. #define X         first
  16. #define Y         second
  17. #define sz(x)     (int)x.size()
  18. #define fr(i,x,y) for (int i = (int)x; i <= (int)y; ++i)
  19. #define rv(i,x,y) for (int i = (int)x; i >= (int)y; --i)
  20. #define bcnt(x)   __builtin_popcount(x)
  21. #define bcntll(x) __builtin_popcountll(x)
  22. #define bg(x)     " [ " << #x << " : " << (x) << " ] "
  23. #define un(x)     sort(x.begin(), x.end()), \
  24.   x.erase(unique(x.begin(), x.end()), x.end())
  25. using   ll  =     long long;
  26. using   ull =     unsigned long long;
  27. using   ff  =     long double;
  28. using   pii =     pair<int,int>;
  29. using   pil =     pair<int,ll>;
  30. using   pll =     pair<ll,ll>;
  31. using   vi  =     vector <int>;
  32. using   vl  =     vector<ll>;
  33. using   vvi =     vector <vi>;
  34. using   vvl =     vector <vl>;
  35. using   vp  =     vector <pii>;
  36. using   vvp =     vector <vp>;
  37. typedef tree
  38. < int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update>
  39. ordered_set;
  40.  
  41. struct chash {
  42.   int operator () (pii x) const { return x.X*31 + x.Y; }
  43. };
  44. gp_hash_table <pii, int, chash> gmp;
  45.  
  46. #if __cplusplus > 201103L
  47. seed_seq seq{
  48.   (uint64_t) chrono::duration_cast<chrono::nanoseconds>
  49.     (chrono::high_resolution_clock::now().time_since_epoch()).count(),
  50.     (uint64_t) __builtin_ia32_rdtsc(),
  51.     (uint64_t) (uintptr_t) make_unique<char>().get()
  52. };
  53. mt19937 rng(seq); //uniform_int_distribution<int> (l, h)(rng); //[low, high]
  54. #else
  55. auto seed = chrono::high_resolution_clock::now().time_since_epoch().count();
  56. mt19937 rng(seed);
  57. #endif
  58.  
  59. #ifdef CONVICTION
  60. void __print(int x) {cerr << x;}
  61. void __print(long x) {cerr << x;}
  62. void __print(long long x) {cerr << x;}
  63. void __print(unsigned x) {cerr << x;}
  64. void __print(unsigned long x) {cerr << x;}
  65. void __print(unsigned long long x) {cerr << x;}
  66. void __print(float x) {cerr << x;}
  67. void __print(double x) {cerr << x;}
  68. void __print(long double x) {cerr << x;}
  69. void __print(char x) {cerr << '\'' << x << '\'';}
  70. void __print(const char *x) {cerr << '\"' << x << '\"';}
  71. void __print(const string &x) {cerr << '\"' << x << '\"';}
  72. void __print(bool x) {cerr << (x ? "true" : "false");}
  73.  
  74. template<typename T, typename V>
  75. void __print(const pair<T, V> &x) {cerr << '{'; __print(x.first); cerr << ','; __print(x.second); cerr << '}';}
  76. template<typename T>
  77. void __print(const T &x) {int f = 0; cerr << '{'; for (auto &i: x) cerr << (f++ ? "," : ""), __print(i); cerr << "}";}
  78. void _print() {cerr << "]" << endl;}
  79. template <typename T, typename... V>
  80. void _print(T t, V... v) {__print(t); if (sizeof...(v)) cerr << ", "; _print(v...);}
  81. #define debug(x...) cerr << "[" << #x << "] = ["; _print(x)
  82. #else
  83. #define debug(x...)
  84. #endif
  85. //         __                                           __
  86. //        (**)                                         (**)
  87. //        IIII                                         IIII
  88. //        ####                                         ####
  89. //        HHHH     Madness comes, and madness goes     HHHH
  90. //        HHHH    An insane place, with insane moves   HHHH
  91. //        ####   Battles without, for battles within   ####
  92. //     ___IIII___        Where evil lives,          ___IIII___
  93. //  .-`_._"**"_._`-.      and evil rules         .-`_._"**"_._`-.
  94. // |/``  .`\/`.  ``\|    Breaking them up,      |/``  .`\/`.  ``\|
  95. // `     }    {     '  just breaking them in    `     }    {     '
  96. //       ) () (  Quickest way out, quickest way wins  ) () (
  97. //       ( :: )      Never disclose, never betray     ( :: )
  98. //       | :: |   Cease to speak or cease to breath   | :: |
  99. //       | )( |        And when you kill a man,       | )( |
  100. //       | || |          you're a murderer            | || |
  101. //       | || |             Kill many                 | || |
  102. //       | || |        and you're a conqueror         | || |
  103. //       | || |        Kill them all ... Ooh..        | || |
  104. //       | || |           Oh you're a God!            | || |
  105. //       ( () )                       -Megadeth       ( () )
  106. //        \  /                                         \  /
  107. //         \/                                           \/
  108. /*}}}*/
  109. /*****************************************************************************/
  110. //Don’t practice until you get it right. Practice until you can’t get it wrong
  111.  
  112. vector <int> mark;
  113. vector <int> mp;
  114.  
  115. class seg_less { /*{{{*/
  116.   // Recurisve Segment Tree with lazy propogation for "less than" library
  117.   // This library is created by Priyanshu Shrivastav (mr.convict)
  118.   // https://github.com/convict-git/sport_coding/blob/master/cplib/snippets/segment_tree_less.cpp
  119.   using ll = long long;
  120.   public:
  121.     static const int MXN = (int)2e5 + 10;
  122.     int sz;
  123.     int ar[MXN];
  124.     int lz[4 * MXN];
  125.  
  126.     struct Node {
  127.       int sz, bg;
  128.       pair <int, int> *v;
  129.       int *minNode;
  130.  
  131.       void update_node(Node left, Node right) {
  132.         assert (sz == left.sz + right.sz);
  133.         for (int i = 0; i < left.sz; ++i) v[i] = left.v[i];
  134.         for (int i = 0; i < right.sz; ++i) v[i + left.sz] = right.v[i];
  135.         sort (v, v + sz);
  136.         minNode[0] = mark[mp[v[0].second]];
  137.         for (int i = 1; i < sz; ++i) {
  138.           minNode[i] = min(minNode[i - 1], mark[mp[v[i].second]]);
  139.         }
  140.       }
  141.  
  142.       void add_val (int x) {
  143.         for (int i = 0; i < sz; ++i) v[i].first += x;
  144.       }
  145.  
  146.       int get (int x) {
  147.         int l = 0, h = sz - 1;
  148.         while (l <= h) {
  149.           int g = (l + h)/2;
  150.           if (v[g].first <= x) l = g + 1;
  151.           else h = g - 1;
  152.         }
  153.         return (h >= 0 ? minNode[h] : INT_MAX);
  154.       }
  155.     };
  156.  
  157.     Node seg[4 * MXN];
  158.  
  159.     seg_less(int n, vector <int> Ar) {
  160.       sz = n;
  161.       assert((int)Ar.size() == n);
  162.       for (int i = 0; i < sz; ar[i] = Ar[i], ++i);
  163.       create(0, n - 1, 0);
  164.     }
  165.  
  166.     void create (int l, int r, int x) {
  167.       seg[x].bg = l;
  168.       seg[x].sz = r - l + 1;
  169.       seg[x].v = new pair <int, int> [seg[x].sz];
  170.       seg[x].minNode = new int [seg[x].sz];
  171.  
  172.       if (l == r)
  173.       {
  174.         seg[x].v[0] = make_pair(ar[l], l);
  175.         seg[x].minNode[0] = mark[mp[l]];
  176.         return;
  177.       }
  178.       int mid = (l + r)/2;
  179.       create(l, mid, x + x + 1);
  180.       create(mid + 1, r, x + x + 2);
  181.       seg[x].update_node(seg[x + x + 1], seg[x + x + 2]);
  182.     }
  183.  
  184.     void lz_upd(int l, int r, int x) {
  185.       if (lz[x] != 0) {
  186.         seg[x].add_val(lz[x]);
  187.         if (l != r)
  188.         {
  189.           lz[x + x + 1] += lz[x];
  190.           lz[x + x + 2] += lz[x];
  191.         }
  192.         lz[x] = 0;
  193.         return;
  194.       }
  195.     }
  196.  
  197.     void upd(int ql, int qr, int val, int l, int r, int x) {
  198.       lz_upd(l, r, x);
  199.       if (l > qr || r < ql) return;
  200.       if (l >= ql && r <= qr) {
  201.         seg[x].add_val(val);
  202.         if (l != r)
  203.         {
  204.           lz[x + x + 1] += val;
  205.           lz[x + x + 2] += val;
  206.         }
  207.         return;
  208.       }
  209.       int mid = (l + r)/2;
  210.       upd(ql, qr, val, l, mid, x + x + 1);
  211.       upd(ql, qr, val, mid + 1, r, x + x + 2);
  212.       seg[x].update_node(seg[x + x + 1], seg[x + x + 2]);
  213.     }
  214.  
  215.     int get (int ql, int qr, int l, int r, int x, int limit) {
  216.       lz_upd(l, r, x);
  217.       if (l > qr || r < ql) return INT_MAX;
  218.       if (l >= ql && r <= qr) return seg[x].get(limit);
  219.  
  220.       int mid = (l + r)/2;
  221.       int lq = get(ql, qr, l, mid, x + x + 1, limit);
  222.       int rq = get(ql, qr, mid + 1, r, x + x + 2, limit);
  223.       return min(lq, rq);
  224.     }
  225.  
  226.     void update_range (int ql, int qr, int val) {
  227.       upd(ql, qr, val, 0, sz - 1, 0);
  228.     }
  229.  
  230.     int query_range_less (int ql, int qr, int limit) {
  231.       return get (ql, qr, 0, sz - 1, 0, limit);
  232.     }
  233. }; /*}}}*/
  234.  
  235. void solve() {
  236.   int n, r;
  237.   cin >> n >> r;
  238.   mark.assign(n, 0);
  239.   mp.assign(2 * n, 0);
  240.   for (int i = 0; i < n; ++i) cin >> mark[i];
  241.  
  242.   int idx = 0;
  243.   vector <int> F(n), L(n);
  244.   vector <int> depth(n);
  245.   vector <vector <int>> T(n, vector <int>());
  246.   vector <int> euler;
  247.  
  248.   for (int i = 0; i < n - 1; ++i) {
  249.     int u, v;
  250.     cin >> u >> v;
  251.     --u, --v;
  252.     T[u].push_back(v);
  253.     T[v].push_back(u);
  254.   }
  255.  
  256.   vector <bool> vis(n);
  257.   function <void(int, int)> dfs = [&] (int u, int d) {
  258.     vis[u] = true;
  259.     depth[u] = d;
  260.     mp[idx] = u;
  261.     F[u] = idx++;
  262.  
  263.     for (int v : T[u]) if (!vis[v])
  264.       dfs(v, d + 1);
  265.  
  266.     mp[idx] = u;
  267.     L[u] = idx++;
  268.   };
  269.  
  270.   dfs(r - 1, 0);
  271.  
  272.   vector <int> ar(2 * n);
  273.   for (int i = 0; i < 2 * n; ++i) {
  274.     ar[i] = depth[mp[i]];
  275.   }
  276.  
  277.   seg_less ST(2 * n, ar);
  278.  
  279.   int q;
  280.   cin >> q;
  281.   int lst = 0;
  282.   while (q--) {
  283.     int pp, qq;
  284.     cin >> pp >> qq;
  285.     int x = (pp + lst) % n + 1;
  286.     int k = (qq + lst) % n;
  287.     --x;
  288.     // dist(y, x) = depth[y] - depth[x] <= k
  289.     // depth[y] <= depth[x] + k
  290.  
  291.     int res = ST.query_range_less(F[x], L[x], k + depth[x]);
  292.     cout << res << '\n';
  293.     lst = res;
  294.   }
  295. }
  296.  
  297. signed main() {
  298.   IOS; PREC;
  299.   int tc = 1;
  300.   // cin >> tc;
  301.   for (int Tt = 1; Tt <= tc; ++Tt) {
  302.     // cout << "Case #" << Tt << ": ";
  303.     solve();
  304.   }
  305.   return EXIT_SUCCESS;
  306. }
Add Comment
Please, Sign In to add comment