fork download
  1. #include <bits/stdc++.h>
  2. #define MAXN 200000
  3. using namespace std;
  4. typedef long long LL;
  5. vector<int> Grafo[MAXN];
  6. int t, p[MAXN], depth[MAXN], discover[MAXN], inn[MAXN], outt[MAXN], subtree[MAXN];
  7. void dfs(int nodo = 0, int padre = -1, int dept = 0){
  8. p[nodo] = padre;
  9. depth[nodo] = dept;
  10. discover[t] = nodo;
  11. inn[nodo] = t++;
  12. subtree[nodo] = 1;
  13. for(auto x : Grafo[nodo]) dfs(x, nodo, dept+1), subtree[nodo] += subtree[x];
  14. outt[nodo] = t-1;
  15. }
  16. int catena, Head[MAXN], last[MAXN], indchain[MAXN], chainsize[MAXN], chainpos[MAXN];
  17. void HLD(int nodo = 0){
  18. if(Head[catena] == -1)
  19. Head[catena] = nodo;
  20. indchain[nodo] = catena;
  21. chainpos[nodo] = chainsize[catena];
  22. chainsize[catena]++;
  23. int Max = -1, ind = -1;
  24. for(auto x : Grafo[nodo])
  25. if(subtree[x] > Max)
  26. Max = subtree[x], ind = x;
  27. if(ind != -1)
  28. HLD(ind);
  29. else
  30. last[catena] = nodo;
  31. for(auto x : Grafo[nodo])
  32. if(x != ind){
  33. catena++;
  34. HLD(x);
  35. }
  36. }
  37. LL res[MAXN];
  38. LL calculate(int nodo, LL k){
  39. if(k == 0) return 0;
  40. LL sum = 0;
  41. for(auto x : Grafo[nodo])
  42. if(indchain[x] != indchain[nodo])
  43. sum += calculate(x, k-1)+k;
  44. LL livelli = depth[last[indchain[nodo]]]-depth[nodo];
  45. sum += -livelli*(livelli-1)/2 + livelli*k;
  46. return sum;
  47. }
  48.  
  49. void calcola_disagio(int N, int Q, int P[], int K[], int u[], int v[], long long risposta[]){
  50. for(int i = 2; i <= N; i++)
  51. Grafo[P[i]-1].push_back(i-1);
  52. dfs(); HLD();
  53. for(int i = 0; i < N; i++)
  54. res[i] = calculate(i, K[i+1]);
  55. for(int i = 0, r = 0; i < Q; ++i){
  56. if(v[i] == -1){
  57. u[i]--;
  58. risposta[r++] = res[u[i]];
  59. }
  60. else{
  61. u[i]--; v[i]--;
  62. int pu = p[u[i]];
  63. auto it = find(Grafo[pu].begin(), Grafo[pu].end(), u[i]);
  64. Grafo[pu].erase(it);
  65. Grafo[v[i]].push_back(u[i]);
  66. p[u[i]] = v[i];
  67. int attuale = pu;
  68. int dep = depth[u[i]];
  69. depth[u[i]] = depth[v[i]]+1;
  70. while(attuale != -1){
  71. if((dep-depth[attuale]-1) < K[attuale+1])
  72. res[attuale] -= K[attuale+1]-(dep-depth[attuale]-1);
  73. attuale = p[attuale];
  74. }
  75. attuale = v[i];
  76. dep = depth[u[i]];
  77. while(attuale != -1){
  78. if((dep-depth[attuale]-1) < K[attuale+1])
  79. res[attuale] += K[attuale+1]-(dep-depth[attuale]-1);
  80. attuale = p[attuale];
  81. }
  82. }
  83. }
  84. }
  85.  
  86.  
  87.  
  88.  
  89. main(){
  90. int N, Q; cin >> N >> Q;
  91. int P[N+1], K[N+1], u[Q], v[Q];
  92. for(int i = 1; i <= N; i++) cin >> P[i];
  93. for(int i = 1; i <= N; i++) cin >> K[i];
  94. int R = 0;
  95. for(int i = 0; i < Q; i++){
  96. cin >> u[i] >> v[i];
  97. if(v[i] == -1)
  98. R++;
  99. }
  100. long long risposta[R];
  101. calcola_disagio(N, Q, P, K, u, v, risposta);
  102. for(int i = 0; i < R; i++)
  103. cout << risposta[i] << endl;
  104. }
  105.  
Success #stdin #stdout 0s 8112KB
stdin
38 38
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 
1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 36 -1
37 1
22 -1
36 1
19 -1
35 1
2 -1
34 1
19 -1
33 1
19 -1
32 1
32 -1
31 1
37 -1
30 1
36 -1
29 1
3 -1
28 1
20 -1
27 1
11 -1
26 1
8 -1
25 1
23 -1
24 1
9 -1
23 1
14 -1
22 1
38 -1
21 1
33 -1
20 1
16 -1
19 1
stdout
1999999999
14999999894
16999999862
32999999469
14999999891
13999999904
999999995
1000000000
999999999
25999999666
7999999962
15999999869
17999999835
1999999986
14999999881
8999999949
0
999999996
3999999976