cincout

Найти ближайшую

Jan 14th, 2020
71
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.58 KB | None | 0 0
  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstdlib>
  4. #include <algorithm>
  5. #include <cmath>
  6. #include <vector>
  7. #include <set>
  8. #include <map>
  9. #include <unordered_set>
  10. #include <unordered_map>
  11. #include <queue>
  12. #include <ctime>
  13. #include <cassert>
  14. #include <complex>
  15. #include <numeric>
  16. #include <string>
  17. #include <cstring>
  18. #include <chrono>
  19. #include <random>
  20. #include <queue>
  21. #include <bitset>
  22. using namespace std;
  23.  
  24. typedef long long ll;
  25. typedef pair<int, int> pii;
  26. typedef pair<ll, int> pli;
  27. typedef pair<ll, ll> pll;
  28. typedef long double ld;
  29. #define mp make_pair
  30. #define str(a) a.c_str()
  31.  
  32. mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
  33.  
  34. const int N = 2e5;
  35. const int L = 17;
  36. const int INF = 1e9;
  37.  
  38. vector<int> a[N];
  39. int col[N], mark[N];
  40. unordered_map <int, int> m[N];
  41. int n;
  42. vector<int> lst[N];
  43.  
  44. int h[N], up[N][L];
  45. int tin[N], tout[N], ss, sz[N];
  46.  
  47. void buildLca(int u = 0, int pr = 0, int lvl = 0) {
  48. tin[u] = ss++;
  49. h[u] = lvl;
  50. up[u][0] = pr;
  51. for (int i = 1; i < L; ++i) {
  52. up[u][i] = up[up[u][i - 1]][i - 1];
  53. }
  54. for (int v : a[u]) {
  55. if (v == pr) continue;
  56. buildLca(v, u, lvl + 1);
  57. }
  58. tout[u] = ss++;
  59. }
  60.  
  61. bool isUpper(int a, int b) {
  62. return tin[a] <= tin[b] && tout[b] <= tout[a];
  63. }
  64.  
  65. int getLca(int u, int v) {
  66. if (isUpper(u, v))
  67. return u;
  68. if (isUpper(v, u))
  69. return v;
  70. for (int i = L - 1; i > -1; --i) {
  71. if (!isUpper(up[u][i], v)) {
  72. u = up[u][i];
  73. }
  74. }
  75. return up[u][0];
  76. }
  77.  
  78. int getDist(int a, int b) {
  79. return h[a] + h[b] - 2 * h[getLca(a, b)];
  80. }
  81.  
  82. void reSize(int u, int p) {
  83. sz[u] = 1;
  84. for (int v : a[u]) {
  85. if (mark[v] || v == p) continue;
  86. reSize(v, u);
  87. sz[u] += sz[v];
  88. }
  89. }
  90.  
  91. int findCentroid(int u, int p, int rootSize) {
  92. int bad = -1;
  93. for (int v : a[u]) {
  94. if (mark[v] || v == p) continue;
  95. if (sz[v] > rootSize / 2) {
  96. bad = v;
  97. }
  98. }
  99. if (bad == -1) {
  100. return u;
  101. }
  102. return findCentroid(bad, u, rootSize);
  103. }
  104.  
  105. void upd(int node, int color, int lvl) {
  106. if (m[node].count(color) == 0) {
  107. m[node][color] = lvl;
  108. return;
  109. }
  110. m[node][color] = min(m[node][color], lvl);
  111. }
  112.  
  113. void push(int u, int p, int c, int lvl) {
  114. lst[u].push_back(c);
  115. upd(c, col[u], lvl);
  116. for (int v : a[u]) {
  117. if (v == p || mark[v]) continue;
  118. push(v, u, c, lvl + 1);
  119. }
  120. }
  121.  
  122. void buildCentroids(int vertex = 0) {
  123. reSize(vertex, vertex);
  124. int x = findCentroid(vertex, vertex, sz[vertex]);
  125. mark[x] = 1;
  126. lst[x].push_back(x);
  127. upd(x, col[x], 0);
  128. for (int v : a[x]) {
  129. if (mark[v]) continue;
  130. push(v, x, x, 1);
  131. }
  132. for (int v : a[x]) {
  133. if (mark[v]) continue;
  134. buildCentroids(v);
  135. }
  136. }
  137.  
  138. int main() {
  139. scanf("%d", &n);
  140.  
  141. for (int i = 1; i < n; ++i) {
  142. int p;
  143. scanf("%d", &p);
  144. a[p].push_back(i);
  145. a[i].push_back(p);
  146. }
  147.  
  148. for (int i = 0; i < n; ++i) {
  149. scanf("%d", &col[i]);
  150. }
  151.  
  152. buildLca();
  153. buildCentroids();
  154.  
  155. int q;
  156. scanf("%d", &q);
  157.  
  158. while (q--) {
  159. int v, c;
  160. scanf("%d %d", &v, &c);
  161. int res = INF;
  162. for (int i : lst[v]) {
  163. int add = INF;
  164. if (m[i].count(c)) {
  165. add = min(add, m[i][c]);
  166. }
  167. res = min(res, getDist(v, i) + add);
  168. }
  169. if (res == INF) res = -1;
  170. printf("%d ", res);
  171. }
  172.  
  173.  
  174. return 0;
  175. }
Add Comment
Please, Sign In to add comment