Advertisement
vlatkovski

Tourist segment tree

Jul 31st, 2019
362
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.77 KB | None | 0 0
  1. /**
  2.  *    author:  tourist
  3.  *    created: 07.02.2019 17:50:31      
  4. **/
  5. #include <bits/stdc++.h>
  6.  
  7. using namespace std;
  8.  
  9. string to_string(string s) {
  10.   return '"' + s + '"';
  11. }
  12.  
  13. string to_string(const char* s) {
  14.   return to_string((string) s);
  15. }
  16.  
  17. string to_string(bool b) {
  18.   return (b ? "true" : "false");
  19. }
  20.  
  21. template <typename A, typename B>
  22. string to_string(pair<A, B> p) {
  23.   return "(" + to_string(p.first) + ", " + to_string(p.second) + ")";
  24. }
  25.  
  26. template <typename A>
  27. string to_string(A v) {
  28.   bool first = true;
  29.   string res = "{";
  30.   for (const auto &x : v) {
  31.     if (!first) {
  32.       res += ", ";
  33.     }
  34.     first = false;
  35.     res += to_string(x);
  36.   }
  37.   res += "}";
  38.   return res;
  39. }
  40.  
  41. void debug_out() { cerr << endl; }
  42.  
  43. template <typename Head, typename... Tail>
  44. void debug_out(Head H, Tail... T) {
  45.   cerr << " " << to_string(H);
  46.   debug_out(T...);
  47. }
  48.  
  49. #ifdef LOCAL
  50. #define debug(...) cerr << "[" << #__VA_ARGS__ << "]:", debug_out(__VA_ARGS__)
  51. #else
  52. #define debug(...) 42
  53. #endif
  54.  
  55. class segtree {
  56.  public:
  57.   struct node {
  58.     // don't forget to set default value (used for leaves)
  59.     // not necessarily neutral element!
  60.     long long mn = 0;
  61.     long long add = 0;
  62.  
  63.     void apply(int l, int r, long long v) {
  64.       mn += v;
  65.       add += v;
  66.     }
  67.   };
  68.  
  69.   node unite(const node &a, const node &b) const {
  70.     node res;
  71.     res.mn = min(a.mn, b.mn);
  72.     return res;
  73.   }
  74.  
  75.   inline void push(int x, int l, int r) {
  76.     int y = (l + r) >> 1;
  77.     int z = x + ((y - l + 1) << 1);
  78.     // push from x into (x + 1) and z
  79.     if (tree[x].add != 0) {
  80.       tree[x + 1].apply(l, y, tree[x].add);
  81.       tree[z].apply(y + 1, r, tree[x].add);
  82.       tree[x].add = 0;
  83.     }
  84.   }
  85.  
  86.   inline void pull(int x, int z) {
  87.     tree[x] = unite(tree[x + 1], tree[z]);
  88.   }
  89.  
  90.   int n;
  91.   vector<node> tree;
  92.  
  93.   void build(int x, int l, int r) {
  94.     if (l == r) {
  95.       return;
  96.     }
  97.     int y = (l + r) >> 1;
  98.     int z = x + ((y - l + 1) << 1);
  99.     build(x + 1, l, y);
  100.     build(z, y + 1, r);
  101.     pull(x, z);
  102.   }
  103.  
  104.   template <typename M>
  105.   void build(int x, int l, int r, const vector<M> &v) {
  106.     if (l == r) {
  107.       tree[x].apply(l, r, v[l]);
  108.       return;
  109.     }
  110.     int y = (l + r) >> 1;
  111.     int z = x + ((y - l + 1) << 1);
  112.     build(x + 1, l, y, v);
  113.     build(z, y + 1, r, v);
  114.     pull(x, z);
  115.   }
  116.  
  117.   node get(int x, int l, int r, int ll, int rr) {
  118.     if (ll <= l && r <= rr) {
  119.       return tree[x];
  120.     }
  121.     int y = (l + r) >> 1;
  122.     int z = x + ((y - l + 1) << 1);
  123.     push(x, l, r);
  124.     node res{};
  125.     if (rr <= y) {
  126.       res = get(x + 1, l, y, ll, rr);
  127.     } else {
  128.       if (ll > y) {
  129.         res = get(z, y + 1, r, ll, rr);
  130.       } else {
  131.         res = unite(get(x + 1, l, y, ll, rr), get(z, y + 1, r, ll, rr));
  132.       }
  133.     }
  134.     pull(x, z);
  135.     return res;
  136.   }
  137.  
  138.   template <typename... M>
  139.   void modify(int x, int l, int r, int ll, int rr, const M&... v) {
  140.     if (ll <= l && r <= rr) {
  141.       tree[x].apply(l, r, v...);
  142.       return;
  143.     }
  144.     int y = (l + r) >> 1;
  145.     int z = x + ((y - l + 1) << 1);
  146.     push(x, l, r);
  147.     if (ll <= y) {
  148.       modify(x + 1, l, y, ll, rr, v...);
  149.     }
  150.     if (rr > y) {
  151.       modify(z, y + 1, r, ll, rr, v...);
  152.     }
  153.     pull(x, z);
  154.   }
  155.  
  156.   int find_first_knowingly(int x, int l, int r, const function<bool(const node&)> &f) {
  157.     if (l == r) {
  158.       return l;
  159.     }
  160.     push(x, l, r);
  161.     int y = (l + r) >> 1;
  162.     int z = x + ((y - l + 1) << 1);
  163.     int res;
  164.     if (f(tree[x + 1])) {
  165.       res = find_first_knowingly(x + 1, l, y, f);
  166.     } else {
  167.       res = find_first_knowingly(z, y + 1, r, f);
  168.     }
  169.     pull(x, z);
  170.     return res;
  171.   }
  172.  
  173.   int find_first(int x, int l, int r, int ll, int rr, const function<bool(const node&)> &f) {
  174.     if (ll <= l && r <= rr) {
  175.       if (!f(tree[x])) {
  176.         return -1;
  177.       }
  178.       return find_first_knowingly(x, l, r, f);
  179.     }
  180.     push(x, l, r);
  181.     int y = (l + r) >> 1;
  182.     int z = x + ((y - l + 1) << 1);
  183.     int res = -1;
  184.     if (ll <= y) {
  185.       res = find_first(x + 1, l, y, ll, rr, f);
  186.     }
  187.     if (rr > y && res == -1) {
  188.       res = find_first(z, y + 1, r, ll, rr, f);
  189.     }
  190.     pull(x, z);
  191.     return res;
  192.   }
  193.  
  194.   int find_last_knowingly(int x, int l, int r, const function<bool(const node&)> &f) {
  195.     if (l == r) {
  196.       return l;
  197.     }
  198.     push(x, l, r);
  199.     int y = (l + r) >> 1;
  200.     int z = x + ((y - l + 1) << 1);
  201.     int res;
  202.     if (f(tree[z])) {
  203.       res = find_last_knowingly(z, y + 1, r, f);
  204.     } else {
  205.       res = find_last_knowingly(x + 1, l, y, f);
  206.     }
  207.     pull(x, z);
  208.     return res;
  209.   }
  210.  
  211.   int find_last(int x, int l, int r, int ll, int rr, const function<bool(const node&)> &f) {
  212.     if (ll <= l && r <= rr) {
  213.       if (!f(tree[x])) {
  214.         return -1;
  215.       }
  216.       return find_last_knowingly(x, l, r, f);
  217.     }
  218.     push(x, l, r);
  219.     int y = (l + r) >> 1;
  220.     int z = x + ((y - l + 1) << 1);
  221.     int res = -1;
  222.     if (rr > y) {
  223.       res = find_last(z, y + 1, r, ll, rr, f);
  224.     }
  225.     if (ll <= y && res == -1) {
  226.       res = find_last(x + 1, l, y, ll, rr, f);
  227.     }
  228.     pull(x, z);
  229.     return res;
  230.   }
  231.  
  232.   segtree(int _n) : n(_n) {
  233.     assert(n > 0);
  234.     tree.resize(2 * n - 1);
  235.     build(0, 0, n - 1);
  236.   }
  237.  
  238.   template <typename M>
  239.   segtree(const vector<M> &v) {
  240.     n = v.size();
  241.     assert(n > 0);
  242.     tree.resize(2 * n - 1);
  243.     build(0, 0, n - 1, v);
  244.   }
  245.  
  246.   node get(int ll, int rr) {
  247.     assert(0 <= ll && ll <= rr && rr <= n - 1);
  248.     return get(0, 0, n - 1, ll, rr);
  249.   }
  250.  
  251.   node get(int p) {
  252.     assert(0 <= p && p <= n - 1);
  253.     return get(0, 0, n - 1, p, p);
  254.   }
  255.  
  256.   template <typename... M>
  257.   void modify(int ll, int rr, const M&... v) {
  258.     assert(0 <= ll && ll <= rr && rr <= n - 1);
  259.     modify(0, 0, n - 1, ll, rr, v...);
  260.   }
  261.  
  262.   // find_first and find_last call all FALSE elements
  263.   // to the left (right) of the sought position exactly once
  264.  
  265.   int find_first(int ll, int rr, const function<bool(const node&)> &f) {
  266.     assert(0 <= ll && ll <= rr && rr <= n - 1);
  267.     return find_first(0, 0, n - 1, ll, rr, f);
  268.   }
  269.  
  270.   int find_last(int ll, int rr, const function<bool(const node&)> &f) {
  271.     assert(0 <= ll && ll <= rr && rr <= n - 1);
  272.     return find_last(0, 0, n - 1, ll, rr, f);
  273.   }
  274. };
  275.  
  276. int main() {
  277.   ios::sync_with_stdio(false);
  278.   cin.tie(0);
  279.   int n, tt;
  280.   cin >> n >> tt;
  281.   vector<int> p(n);
  282.   vector<int> w(n);
  283.   for (int i = 1; i < n; i++) {
  284.     cin >> p[i] >> w[i];
  285.     p[i]--;
  286.   }
  287.   vector<vector<int>> qs(n);
  288.   vector<int> L(tt), R(tt), v(tt);
  289.   vector<long long> res(tt, -1);
  290.   for (int i = 0; i < tt; i++) {
  291.     cin >> v[i] >> L[i] >> R[i];
  292.     v[i]--; L[i]--; R[i]--;
  293.     qs[v[i]].push_back(i);
  294.   }
  295.   vector<long long> dst(n);
  296.   for (int i = 1; i < n; i++) {
  297.     dst[i] = dst[p[i]] + w[i];
  298.   }
  299.   vector<int> is_leaf(n, 1);
  300.   for (int i = 1; i < n; i++) {
  301.     is_leaf[p[i]] = 0;
  302.   }
  303.   const long long inf = (long long) 1e18;
  304.   for (int i = 0; i < n; i++) {
  305.     if (!is_leaf[i]) {
  306.       dst[i] = inf;
  307.     }
  308.   }
  309.   segtree st(dst);
  310.   vector<int> stk;
  311.   vector<int> to(n, n - 1);
  312.   for (int i = 0; i < n; i++) {
  313.     while (!stk.empty() && stk.back() != p[i]) {
  314.       int u = stk.back();
  315.       to[u] = i - 1;
  316.       stk.pop_back();
  317.     }
  318.     stk.push_back(i);
  319.   }
  320.   debug(to);
  321.   stk.clear();
  322.   for (int i = 0; i < n; i++) {
  323.     while (!stk.empty() && stk.back() != p[i]) {
  324.       int u = stk.back();
  325.       st.modify(0, n - 1, -w[u]);
  326.       st.modify(u, to[u], 2 * w[u]);
  327.       stk.pop_back();
  328.     }
  329.     stk.push_back(i);
  330.     st.modify(0, n - 1, w[i]);
  331.     st.modify(i, to[i], -2 * w[i]);
  332.     for (int id : qs[i]) {
  333.       res[id] = st.get(L[id], R[id]).mn;
  334.     }
  335.   }
  336.   for (int i = 0; i < tt; i++) {
  337.     cout << res[i] << '\n';
  338.   }
  339.   return 0;
  340. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement