Advertisement
ke_timofeeva7

centroid decomposition

Aug 13th, 2023
48
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.80 KB | None | 0 0
  1. #include <iostream>
  2. #include <string>
  3. #include <sstream>
  4. #include <cmath>
  5. #include <memory.h>
  6. #include <algorithm>
  7. #include <stack>
  8. #include <deque>
  9. #include <iomanip>
  10. #include <stdio.h>
  11. #include <queue>
  12. #include <map>
  13. #include <set>
  14. #include <unordered_map>
  15. #include <unordered_set>
  16. #include <random>
  17. #include <ctime>
  18. #include <cstdlib>
  19. #include <cassert>
  20. #include <iterator>
  21. #include <chrono>
  22. #include <array>
  23. #include <bitset>
  24. #define pii pair <int, int>
  25. #define debug(x) cerr << (#x) << " " << (x) << endl
  26. #define pb push_back
  27. #define all(vc) vc.begin(), vc.end()
  28. #define endl "\n"
  29. using namespace std;
  30.  
  31. mt19937 rnd(chrono::steady_clock::now().time_since_epoch().count());
  32.  
  33. const int LOGN = 19, INF = (long long)(1e9) + 7;
  34.  
  35. vector<int> sz;
  36. vector<bool> used;
  37. vector<int> d;
  38. vector<int> sum;
  39. vector<vector<pii>> sp;
  40. vector<int> idx;
  41. vector<int> euler;
  42. vector<int> logn;
  43.  
  44. int size(vector<vector<pii>>& gr, int v, int pr = -1) {
  45. sz[v] = 1;
  46. for (auto i : gr[v]) {
  47. int u = i.first;
  48. if (u != pr && !used[u]) {
  49. sz[v] += size(gr, u, v);
  50. }
  51. }
  52. return sz[v];
  53. }
  54.  
  55. int centroid(vector<vector<pii>>& gr, int v, int n, int pr) {
  56. for (auto i : gr[v]) {
  57. int u = i.first;
  58. if (u == pr) {
  59. continue;
  60. }
  61. if (sz[u] > n / 2 && !used[u]) {
  62. return centroid(gr, u, n, v);
  63. }
  64. }
  65. used[v] = 1;
  66. return v;
  67. }
  68.  
  69. vector<int> p;
  70.  
  71. void decomposition(vector<vector<pii>>& gr, int n, int k, int v, int pr = -1, int cntr = -1) {
  72. sz.resize(n);
  73. size(gr, v);
  74.  
  75. int cnt = centroid(gr, v, n / k, pr);
  76. p[cnt] = cntr;
  77. k *= 2;
  78.  
  79. for (auto i : gr[cnt]) {
  80. int u = i.first;
  81. if (u == pr || used[u]) {
  82. continue;
  83. }
  84. decomposition(gr, n, k, u, cnt, cnt);
  85. }
  86. return;
  87. }
  88.  
  89. void dfs(vector<vector<pii>>& gr, int v, int pr, int cost = 0) {
  90. d[v] = d[pr] + 1;
  91. sum[v] = sum[pr] + cost;
  92. idx[v] = (int)(euler.size());
  93. euler.push_back(v);
  94. for (auto& u : gr[v]) {
  95. if (u.first != pr) {
  96. dfs(gr, u.first, v, u.second);
  97. }
  98. euler.push_back(v);
  99. }
  100. }
  101.  
  102. int get_lca(int v, int u) {
  103. int l = min(idx[u], idx[v]), r = max(idx[u], idx[v]);
  104. int lvl = logn[r - l + 1];
  105. pii ans = min(sp[lvl][l], sp[lvl][r - (1LL << lvl) + 1]);
  106. return ans.second;
  107. }
  108.  
  109. int get_sum(int u, int v) {
  110. int lca = get_lca(u, v);
  111. if (lca == u) {
  112. return sum[v] - sum[u];
  113. }
  114. if (lca == v) {
  115. return sum[u] - sum[v];
  116. }
  117. return sum[u] + sum[v] - 2 * sum[lca];
  118. }
  119.  
  120. void insert(vector<multiset<int>>& st, int v) {
  121. int u = v;
  122. while (u != -1) {
  123. st[u].insert(get_sum(u, v));
  124. u = p[u];
  125. }
  126. }
  127.  
  128. void erase(vector<multiset<int>>& st, int v) {
  129. int u = v;
  130. while (u != -1) {
  131. st[u].erase(st[u].find(get_sum(u, v)));
  132. u = p[u];
  133. }
  134. }
  135.  
  136. int get_ans(vector<multiset<int>>& st, int v) {
  137. int ans = INF;
  138. int u = v;
  139. while (u != -1) {
  140. if (!st[u].empty()) {
  141. int len = *st[u].begin();
  142. len += get_sum(u, v);
  143. ans = min(ans, len);
  144. }
  145. u = p[u];
  146. }
  147. return ans;
  148. }
  149. signed main() {
  150. ios_base::sync_with_stdio(false);
  151. cin.tie(0);
  152. cout.tie(0);
  153. srand(time(0));
  154.  
  155. int n;
  156. cin >> n;
  157. vector<vector<pii>> gr(n);
  158. for (int i = 1; i < n; i++) {
  159. int a, b, c;
  160. cin >> a >> b >> c;
  161. a--;
  162. b--;
  163. gr[a].push_back({ b, c });
  164. gr[b].push_back({ a, c });
  165. }
  166.  
  167. used.resize(n);
  168. sz.resize(n);
  169. size(gr, 0);
  170.  
  171. p.resize(n, -1);
  172. decomposition(gr, n, 1, 0);
  173. used = vector<bool>(0);
  174. d.resize(n);
  175. sum.resize(n);
  176. idx.resize(n);
  177. dfs(gr, 0, 0);
  178. gr = vector<vector<pii>>(0);
  179.  
  180. logn.resize((int)(euler.size()) + 1);
  181. logn[1] = 0;
  182. for (int i = 2; i <= (int)(euler.size()); i++) {
  183. logn[i] = logn[i / 2] + 1;
  184. }
  185.  
  186. sp.resize(logn[(int)(euler.size())] + 1, vector<pii>((int)(euler.size())));
  187. for (int i = 0; i < euler.size(); i++) {
  188. sp[0][i] = { d[euler[i]], euler[i] };
  189. }
  190. for (int i = 1; (1 << i) <= euler.size(); i++) {
  191. for (int j = 0; j + (1LL << i) <= euler.size(); j++) {
  192. sp[i][j] = min(sp[i - 1][j], sp[i - 1][j + (1LL << (i - 1))]);
  193. }
  194. }
  195.  
  196. vector<multiset<int>> st(n);
  197. insert(st, 0);
  198. int q;
  199. cin >> q;
  200.  
  201. while (q--) {
  202. char type;
  203. cin >> type;
  204. int v;
  205. cin >> v;
  206. v--;
  207.  
  208. if (type == '+') {
  209. insert(st, v);
  210. }
  211. else if (type == '-') {
  212. erase(st, v);
  213. }
  214. else {
  215. cout << get_ans(st, v) << endl;
  216. }
  217. }
  218. return 0;
  219. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement