Wednesday, January 9, 2019

[Codeforces] E. On Changing Tree

Author            : Dipu Kumar Mohanto 
                    CSE, Batch - 6
                    BRUR.
Problem Statement : E. On Changing Tree
Source            : Codeforces
Category          : Data Structure, Graph Theory, Tree
Algorithm         : Heavy Light Decomposition, Segment Tree
Verdict           : Accepted

  1. #include "bits/stdc++.h"  
  2.   
  3. using namespace std;  
  4.   
  5. #define ll           long long int  
  6.   
  7. static const int maxn = 3e5 + 5;  
  8. static const int logn = 21;  
  9. static const ll mod = 1e9 + 7;  
  10.   
  11. vector <int> graph[maxn];  
  12. int depth[maxn];  
  13. int father[maxn][logn];  
  14. int subtreeSize[maxn];  
  15.   
  16. int N;  
  17.   
  18. inline void dfs(int u = 1, int p = -1)  
  19. {  
  20.       for (int i = 1; i < logn; i++) father[u][i] = father[ father[u][i-1] ][i-1];  
  21.       subtreeSize[u] = 1;  
  22.       for (int v : graph[u])  
  23.       {  
  24.             if (v == p) continue;  
  25.             depth[v] = depth[u] + 1;  
  26.             father[v][0] = u;  
  27.             dfs(v, u);  
  28.             subtreeSize[u] += subtreeSize[v];  
  29.       }  
  30. }  
  31.   
  32. int chainHead[maxn];  
  33. int chainNo;  
  34. int chainInd[maxn];  
  35. int ptr;  
  36. int posBase[maxn];  
  37.   
  38. inline void hld(int u = 1, int p = -1)  
  39. {  
  40.       if (chainHead[ chainNo ] == -1) chainHead[ chainNo ] = u;  
  41.       ptr++;  
  42.       posBase[u] = ptr;  
  43.       chainInd[u] = chainNo;  
  44.       int mx = -1;  
  45.       int bigChild = -1;  
  46.       for (int v : graph[u])  
  47.       {  
  48.             if (v == p) continue;  
  49.             if (subtreeSize[v] > mx) mx = subtreeSize[v], bigChild = v;  
  50.       }  
  51.       if (bigChild != -1) hld(bigChild, u);  
  52.       for (int v : graph[u])  
  53.       {  
  54.             if (v == p or v == bigChild) continue;  
  55.             chainNo++;  
  56.             hld(v, u);  
  57.       }  
  58. }  
  59.   
  60. // value of a particular vertex:  
  61. // All the value which are added in the ancestor of node v are also  
  62. // added to node v. So, we can find added value by the sum of all  
  63. // node from root to node v.  
  64. // Now, to find the value of subtraction(i.e. k), we know,  
  65. // if a k value added on u vertex, this affects on v vertex by following,  
  66. //             distance(u, v) * k  
  67. //            = (level[v] - level[u]) * k  
  68. // we know, level[v] is constant. So, we can take level[v] as a common term  
  69. // from all ancestor of v.  
  70. // So, our final ans will be  
  71. //           sum_add - (sum_k * level[v] - sum_u_k)  
  72. // sum_add = all added value in the ancestor of v  
  73. // sum_k = all k value added in the ancestor of v  
  74. // sum_u_k = sum of level[u] * k, where u is ancestor of v  
  75.   
  76. struct segmentTree  
  77. {  
  78.       ll sumOne, sumTwo, sumThree;  
  79.       segmentTree(ll sum1 = 0, ll sum2 = 0, ll sum3 = 0) : sumOne(sum1), sumTwo(sum2), sumThree(sum3) {}  
  80.       inline void assignLeaf(ll sum1, ll sum2, ll sum3)  
  81.       {  
  82.             sumOne = sum1;  
  83.             sumTwo = sum2;  
  84.             sumThree = sum3;  
  85.       }  
  86.       inline void marge(segmentTree &lft, segmentTree &rgt)  
  87.       {  
  88.             sumOne = (lft.sumOne + rgt.sumOne) % mod;  
  89.             sumTwo = (lft.sumTwo + rgt.sumTwo) % mod;  
  90.             sumThree = (lft.sumThree + rgt.sumThree) % mod;  
  91.       }  
  92. } Tree[maxn << 2];  
  93.   
  94. inline void update(int node, int a, int b, int pos, segmentTree tpl)  
  95. {  
  96.       if (a == pos && b == pos)  
  97.       {  
  98.             Tree[node].marge(Tree[node], tpl);  
  99.             return;  
  100.       }  
  101.       int lft = node << 1;  
  102.       int rgt = lft | 1;  
  103.       int mid = (a + b) >> 1;  
  104.       if (pos <= mid)  
  105.       {  
  106.             update(lft, a, mid, pos, tpl);  
  107.       }  
  108.       else if (pos > mid)  
  109.       {  
  110.             update(rgt, mid+1, b, pos, tpl);  
  111.       }  
  112.       Tree[node].marge(Tree[lft], Tree[rgt]);  
  113. }  
  114.   
  115. inline segmentTree query(int node, int a, int b, int i, int j)  
  116. {  
  117.       if (a > b or a > j or b < i) return segmentTree();  
  118.       if (a >= i && b <= j) return Tree[node];  
  119.       int lft = node << 1;  
  120.       int rgt = lft | 1;  
  121.       int mid = (a + b) >> 1;  
  122.       segmentTree p, q, res;  
  123.       p = query(lft, a, mid, i, j);  
  124.       q = query(rgt, mid+1, b, i, j);  
  125.       res.marge(p, q);  
  126.       return res;  
  127. }  
  128.   
  129. inline void updateNode(int u, ll x, ll k)  
  130. {  
  131.       int level = depth[u];  
  132.       int pos = posBase[u];  
  133.       ll mul = (k * (ll)level) % mod;  
  134.       segmentTree tpl = segmentTree(x, k, mul);  
  135.       update(1, 1, N, pos, tpl);  
  136. }  
  137.   
  138. inline segmentTree query_path(int u, int v = 1)  
  139. {  
  140.       segmentTree res = segmentTree();  
  141.       int uChain;  
  142.       int vChain = chainInd[v];  
  143.       while (true)  
  144.       {  
  145.             uChain = chainInd[u];  
  146.             if (uChain == vChain)  
  147.             {  
  148.                   int l = posBase[v];  
  149.                   int r = posBase[u];  
  150.                   assert(l <= r);  
  151.                   segmentTree q = query(1, 1, N, l, r);  
  152.                   res.marge(res, q);  
  153.                   break;  
  154.             }  
  155.             int l = posBase[ chainHead[uChain] ];  
  156.             int r = posBase[u];  
  157.             assert(l <= r);  
  158.             segmentTree q = query(1, 1, N, l, r);  
  159.             res.marge(res, q);  
  160.             u = father[ chainHead[uChain] ][0];  
  161.       }  
  162.       return res;  
  163. }  
  164.   
  165. inline ll query_ans(int u)  
  166. {  
  167.       segmentTree res = query_path(u);  
  168.       ll ans = (res.sumOne - (((res.sumTwo * depth[u]) % mod) - res.sumThree) + mod) % mod;  
  169.       return ans;  
  170. }  
  171.   
  172. inline void init()  
  173. {  
  174.       ptr = 0;  
  175.       chainNo = 0;  
  176.       for (int i = 0; i < maxn; i++)  
  177.       {  
  178.             graph[i].clear();  
  179.             depth[i] = 0;  
  180.             subtreeSize[i] = 0;  
  181.             chainHead[i] = -1;  
  182.             chainInd[i] = 0;  
  183.             posBase[i] = 0;  
  184.             for (int j = 0; j < logn; j++) father[i][j] = 0;  
  185.       }  
  186. }  
  187.   
  188. int main()  
  189. {  
  190.       //freopen("in.txt", "r", stdin);  
  191.   
  192.       init();  
  193.   
  194.       int tnode;  
  195.       scanf("%d", &tnode);  
  196.       for (int v = 2; v <= tnode; v++)  
  197.       {  
  198.             int u;  
  199.             scanf("%d", &u);  
  200.             graph[u].emplace_back(v);  
  201.             graph[v].emplace_back(u);  
  202.       }  
  203.       N = tnode;  
  204.       depth[1] = 1;  
  205.       dfs();  
  206.       hld();  
  207.       int tquery;  
  208.       scanf("%d", &tquery);  
  209.       while (tquery--)  
  210.       {  
  211.             int type;  
  212.             scanf("%d", &type);  
  213.             if (type == 1)  
  214.             {  
  215.                   int u;  
  216.                   ll x, k;  
  217.                   scanf("%d %lld %lld", &u, &x, &k);  
  218.                   updateNode(u, x, k);  
  219.             }  
  220.             else  
  221.             {  
  222.                   int v;  
  223.                   scanf("%d", &v);  
  224.                   ll ans = query_ans(v);  
  225.                   printf("%lld\n", ans);  
  226.             }  
  227.       }  
  228. }  

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.