mr_dot_convict

Codechef-BACREP-mr.convict

Oct 14th, 2019
99
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.15 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. #define IOS       ios_base::sync_with_stdio(false); cin.tie (nullptr)
  15. #define PREC      cout.precision (10); cout << fixed
  16. #define x         first
  17. #define y         second
  18. #define fr(i,x,y) for (int i = x; i <= y; ++i)
  19. #define fR(i,x,y) for (int i = x; i >= y; --i)
  20. #define bg(x)     " [ " << #x << " : " << (x) << " ] "
  21. #define un(x)     sort(x.begin(), x.end()), \
  22.    x.erase(unique(x.begin(), x.end()), x.end())
  23.  
  24. using   ll  =     long long;
  25. using   ull =     unsigned long long;
  26. using   ff  =     long double;
  27. using   pii =     pair<int,int>;
  28. using   pil =     pair<int,ll>;
  29. typedef tree
  30. < int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update>
  31. ordered_set;
  32.  
  33. struct chash {
  34.    int operator () (pii x) const { return x.x*31 + x.y; }
  35. };
  36. gp_hash_table <pii, int, chash> mp;
  37.  
  38. #if __cplusplus > 201103L
  39. seed_seq seq{
  40.    (uint64_t) chrono::duration_cast<chrono::nanoseconds>
  41.       (chrono::high_resolution_clock::now().time_since_epoch()).count(),
  42.       (uint64_t) __builtin_ia32_rdtsc(),
  43.       (uint64_t) (uintptr_t) make_unique<char>().get()
  44. };
  45. mt19937 rng(seq); //uniform_int_distribution<int> (l, h)(rng); //[low, high]
  46. #else
  47. auto seed = chrono::high_resolution_clock::now().time_since_epoch().count();
  48. mt19937 rng(seed);
  49. #endif
  50.  
  51. #define debug(args...) { \
  52.    /* WARNING : do NOT compile this debug func calls with following flags: // \
  53.     * // -D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC -D_FORTIFY_SOURCE=2*/ \
  54.    string _s = #args; replace(_s.begin(), _s.end(), ',', ' ');\
  55.    stringstream _ss(_s); \
  56.    istream_iterator<string> _it(_ss); err(_it, args); \
  57. }
  58. void err(istream_iterator<string> it) {
  59.    it->empty(); cerr << " (Line : " << __LINE__ << ")" << '\n';
  60. }
  61. template<typename T, typename... Args>
  62. void err(istream_iterator<string> it, T a, Args... args) {
  63.    cerr << fixed << setprecision(15)
  64.       << " [ " <<  *it << " : " << a  << " ] "<< ' ';
  65.    err(++it, args...);
  66. }
  67. /*****************************************************************************/
  68. //Don’t practice until you get it right. Practice until you can’t get it wrong
  69.  
  70. class seg_sum {
  71.    public:
  72.       using ll = long long;
  73.       static const int MAXN = (int)2e6 + 10;
  74.       ll seg[4 * MAXN], ar[MAXN];
  75.       int sz;
  76.       seg_sum(int n, vector <ll> Ar) {
  77.          sz = n;
  78.          for (int i = 0; i < sz; seg[i + sz] = Ar[i], ++i);
  79.          build();
  80.       }
  81.       void build() {  // build the tree
  82.          for (int i = sz - 1; i > 0; --i) seg[i] = seg[i << 1] + seg[i << 1|1];
  83.       }
  84.       void modify(int p, int value) {  // set value at position p
  85.          for (seg[p += sz] += value; p > 1; p >>= 1) seg[p>>1] = seg[p] + seg[p^1];
  86.       }
  87.       ll query(int l, int r) {  // sum on interval [l, r)
  88.          ++r;
  89.          ll res = 0;
  90.          for (l += sz, r += sz; l < r; l >>= 1, r >>= 1) {
  91.             if (l&1) res += seg[l++];
  92.             if (r&1) res += seg[--r];
  93.          }
  94.          return res;
  95.       }
  96. };
  97.  
  98. signed main() {
  99.    IOS; PREC;
  100.    const int D = 22;
  101.    int n, q;
  102.    cin >> n >> q;
  103.    int m = n + q;
  104.  
  105.    vector <ll> ar(m), a_entry(2*m + 1), a_xit(2*m + 1);
  106.    vector <vector <int>> T(m, vector <int>());
  107.    vector <vector <int>> table(m, vector <int> (D + 1, -1));
  108.    vector <int> euler, entry(m), xit(m), depth(m);
  109.    vector <bool> is_leaf(m, false);
  110.  
  111.    for (int i = n; i < m - 1; ++i) {
  112.       T[i].push_back(i + 1);
  113.    }
  114.    T[m - 1].push_back(0);
  115.  
  116.    for (int i = 0; i < n - 1; ++i) {
  117.       int u, v;
  118.       cin >> u >> v; --u, --v;
  119.       T[u].push_back(v);
  120.       T[v].push_back(u);
  121.    }
  122.  
  123.    for (int i = 0; i < n; ++i)
  124.       cin >> ar[i];
  125.  
  126.    function <void(int, int, int)> dfs = // O(ND)
  127.       [&] (int u, int pr, int d) -> void {
  128.          depth[u] = d;
  129.  
  130.          euler.push_back(u);
  131.          entry[u] = (int)euler.size();
  132.          a_entry[entry[u]] = ar[u];
  133.  
  134.          for (int k = 1; k <= D; ++k) if (table[u][k - 1] != -1)
  135.             table[u][k] = table[table[u][k - 1]][k - 1];
  136.  
  137.          for (int v : T[u]) {
  138.             if (v == pr) continue;
  139.             table[v][0] = u;
  140.             dfs(v, u, d + 1);
  141.          }
  142.  
  143.          euler.push_back(u);
  144.          xit[u] = (int)euler.size();
  145.          a_xit[xit[u]] = ar[u];
  146.  
  147.          is_leaf[u] = (entry[u] + 1 == xit[u]);
  148.       };
  149.  
  150.    auto walk = [&] (int u, int k) { // O(log(N))
  151.       for (int d = 0; d <= D && u >= 0; ++d) {
  152.          if ((1 << d) & k) u = table[u][d];
  153.       }
  154.       return u;
  155.    };
  156.  
  157.    dfs(n, -1, 0);
  158.    // assert((int)euler.size() == 2*m);
  159.    seg_sum S_entry((int)euler.size() + 1, a_entry);
  160.    seg_sum S_xit((int)euler.size() + 1, a_xit);
  161.  
  162.    struct Query {
  163.       int u, time_el;
  164.    };
  165.    struct Update {
  166.       int u, val, time_el;
  167.    };
  168.    vector <pair <int, ll>> answers;
  169.    vector <vector <Update>> updates(n, vector <Update>());
  170.    vector <vector <Query>> queries(n, vector <Query>());
  171.  
  172.    for (int i = 1; i <= q; ++i) {
  173.       string qs; int u, val;
  174.       cin >> qs;
  175.       if (qs == "?") {
  176.          cin >> u; --u;
  177.          queries[u].push_back({u, i});
  178.       }
  179.       else {
  180.          cin >> u >> val; --u;
  181.          updates[u].push_back({u, val, i});
  182.       }
  183.    }
  184.  
  185.    vector <bool> visited(m, false);
  186.  
  187.    for (int i = entry[0]; i <= xit[0]; ++i) {
  188.       int u = euler[i - 1];
  189.       if (!visited[u]) { // update the system and answer the queries
  190.          for (int j = 0; j < (int)updates[u].size(); ++j) {
  191.             int tm = updates[u][j].time_el;
  192.             int val = updates[u][j].val;
  193.             int v = walk(u, tm);
  194.             ar[v] += val;
  195.             S_entry.modify(entry[v], val);
  196.             S_xit.modify(xit[v], val);
  197.          }
  198.          for (int j = 0; j < (int)queries[u].size(); ++j) {
  199.             int tm = queries[u][j].time_el;
  200.             int v = walk(u, tm);
  201.             if (!is_leaf[u]) { // for non-leaf
  202.                answers.push_back(make_pair(tm, ar[v]));
  203.             }
  204.             else { // for leaf
  205.                ll inc = S_xit.query(xit[u], xit[v]);
  206.                ll exc = S_entry.query(xit[u], xit[v]);
  207.                answers.push_back(make_pair(tm, inc - exc));
  208.             }
  209.          }
  210.          visited[u] = true;
  211.       }
  212.       else { // remove the updates
  213.          for (int j = 0; j < (int)updates[u].size(); ++j) {
  214.             int tm = updates[u][j].time_el;
  215.             int val = updates[u][j].val;
  216.             int v = walk(u, tm);
  217.             ar[v] -= val;
  218.             S_entry.modify(entry[v], -val);
  219.             S_xit.modify(xit[v], -val);
  220.          }
  221.       }
  222.    }
  223.    sort(answers.begin(), answers.end());
  224.    for (auto el : answers) {
  225.       cout << el.y << '\n';
  226.    }
  227.  
  228.    return EXIT_SUCCESS;
  229. }
Add Comment
Please, Sign In to add comment