Advertisement
tumaryui

Untitled

Apr 26th, 2020
279
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.94 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. #define int long long
  3. #define pb push_back
  4. #define pii pair<int,int>
  5. using namespace std;
  6. const int logn = 18, N = 1e5 + 10;
  7. vector<int> gr[N];
  8. int tin[N], tout[N], h[N], up[20][N], timer;
  9.  
  10. void dfs(int v, int pr)
  11. {
  12. tin[v] = ++timer;
  13. up[0][v] = pr;
  14. for(int i = 1; i <= 19; i++)
  15. {
  16. up[i][v] = up[i - 1][up[i - 1][v]];
  17. }
  18. for(int to: gr[v])
  19. {
  20. if(to != pr)
  21. {
  22. h[to] = h[v] + 1;
  23. dfs(to, v);
  24. }
  25. }
  26. tout[v] = timer;
  27. }
  28.  
  29. bool upper(int a, int b)
  30. {
  31. return tin[a] <= tin[b] && tout[a] >= tout[b];
  32. }
  33.  
  34. int lca(int a, int b)
  35. {
  36. if(upper(a, b)) return a;
  37. if(upper(b, a)) return b;
  38.  
  39. for(int i = 19; i >= 0; i--)
  40. {
  41. if(!upper(up[i][a], b))
  42. {
  43. a = up[i][a];
  44. }
  45. }
  46. return up[0][a];
  47. }
  48.  
  49. int len(int a, int b)
  50. {
  51. return h[a] + h[b] - 2 * h[lca(a, b)];
  52. }
  53.  
  54. main()
  55. {
  56. ios_base::sync_with_stdio(0);
  57. cin.tie(0);
  58. cout.tie(0);
  59. int n, m;
  60. cin >> n;
  61. for(int i = 0; i < n - 1; i ++)
  62. {
  63. int l, r;
  64. cin >> l >> r;
  65. gr[l].pb(r);
  66. gr[r].pb(l);
  67. }
  68. dfs(1, 1);
  69. int q;
  70. cin >> q;
  71. //set
  72. auto cmp = [](int a, int b) {return tin[a] < tin[b];};
  73. set<int, decltype(cmp)> cur(cmp);
  74. //
  75. int ans = 0;
  76. while(q--) {
  77. int id;
  78. cin >> id;
  79. if(id == 1) {
  80. int v;
  81. cin >> v;
  82. cur.insert(v);
  83. auto it = cur.find(v);
  84.  
  85. if(cur.size() != 1) {
  86. //already some vers in graph
  87. it++;
  88. if(it != cur.end()) {
  89. //v is not last
  90. int u = *it;
  91. int l = lca(v, u);
  92.  
  93. if(l == 1) {
  94. //v got deeper
  95. it--;
  96. if(it == cur.begin()) {
  97. //v is new
  98. ans += (2 * len(1, v));
  99. } else {
  100. it--;
  101. u = *it;
  102. ans += (2 * len(v, lca(v, u)));
  103. }
  104. } else {
  105. if(l != v) {
  106. ans += (2 * len(v, l));
  107. }
  108. }
  109.  
  110. } else {
  111. //v is last
  112. it--;
  113. it--;
  114. int l = lca(v, *it);
  115. ans += (2 * len(v, l));
  116. }
  117. } else {
  118. // no vers before
  119. ans += (2 * len(1, v));
  120. }
  121. }
  122. if(id == 2) {
  123. int v;
  124. cin >> v;
  125. if(cur.size() == 1) {
  126. //only one v
  127. cur.erase(v);
  128. ans = 0;
  129. } else {
  130. // more vs
  131. auto it = cur.find(v);
  132. it++;
  133. if(it == cur.end()) {
  134. //v is last
  135. it--;
  136. it--;
  137. int u = *it;
  138. int l = lca(u, v);
  139. ans -= (2 * len(l, v));
  140. cur.erase(v);
  141. } else {
  142. // v is not last
  143. int u = *it;
  144. int l = lca(u, v);
  145. if(l == 1) {
  146. // v and next are in diffrt subtrees
  147. it--;
  148. if(it == cur.begin()) {
  149. //v is 1 in subtree
  150. ans -= (2 * len(1, v));
  151. cur.erase(v);
  152. continue;
  153. }
  154. it--;
  155. u = *it;
  156. ans -= (2 * len(v, lca(v, u)));
  157. cur.erase(v);
  158. } else {
  159. //v and next are in one subtree
  160. if(l != v) {
  161. ans -= (2 * len(v, l));
  162. cur.erase(v);
  163. } else {
  164. cur.erase(v);
  165. }
  166. }
  167. }
  168. }
  169. }
  170. if(id == 3) {
  171. cout << ans << endl;
  172. }
  173. }
  174.  
  175. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement