Advertisement
libobil

Untitled

Oct 5th, 2023
28
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.05 KB | None | 0 0
  1. #include <algorithm>
  2. #include <iostream>
  3. #include <numeric>
  4. #include <cstring>
  5. #include <cassert>
  6. #include <bitset>
  7. #include <vector>
  8.  
  9. typedef long long llong;
  10. const int MAXN = 500000 + 10;
  11. const int INF = 1e9;
  12.  
  13. int n;
  14. struct Query
  15. {
  16. int idx;
  17. int to;
  18. char type;
  19.  
  20. Query(){}
  21. Query(int _idx, int _to, char _type)
  22. {
  23. idx = _idx;
  24. to = _to;
  25. type = _type;
  26. }
  27. };
  28.  
  29. std::vector <Query> queries[MAXN];
  30. std::vector <int> one[MAXN];
  31. std::vector <int> two[MAXN];
  32. std::vector <int> oneBegin[MAXN];
  33. std::vector <int> twoBegin[MAXN];
  34. std::vector <int> tourOne;
  35. std::vector <int> tourTwo;
  36. int newNum[MAXN];
  37. int inOne[MAXN];
  38. int inTwo[MAXN];
  39. int outOne[MAXN];
  40. int outTwo[MAXN];
  41. int tree[MAXN];
  42. int ans[MAXN];
  43.  
  44. void buildTourOne(int node, int p)
  45. {
  46. // std::cout << "build tour one: " << node << '\n';
  47. tourOne.push_back(node);
  48. for (const int &i : oneBegin[node])
  49. {
  50. if (i == p) continue;
  51. buildTourOne(i, node);
  52. }
  53. }
  54.  
  55. int timer = 1;
  56. void buildInOutTime(int node, int p)
  57. {
  58. inOne[node] = timer++;
  59. for (const int &i : one[node])
  60. {
  61. if (i == p) continue;
  62. buildInOutTime(i, node);
  63. }
  64.  
  65. outOne[node] = timer - 1;
  66. }
  67.  
  68. void buildTourTwo(int node, int p)
  69. {
  70. inTwo[node] = timer++;
  71. tourTwo.push_back(node);
  72. for (const int &i : two[node])
  73. {
  74. if (i == p) continue;
  75. buildTourTwo(i, node);
  76. }
  77.  
  78. outTwo[node] = timer - 1;
  79. }
  80.  
  81. int oneS[MAXN];
  82. int twoS[MAXN];
  83.  
  84. void findOneS(int node, int p)
  85. {
  86. for (int &i : one[node])
  87. {
  88. if (i == p)
  89. {
  90. std::swap(i, one[node].back());
  91. one[node].pop_back();
  92. break;
  93. }
  94. }
  95.  
  96. oneS[node] = 1;
  97. for (const int &i : one[node])
  98. {
  99. findOneS(i, node);
  100. oneS[node] += oneS[i];
  101. }
  102. }
  103.  
  104. void findTwoS(int node, int p)
  105. {
  106. for (int &i : two[node])
  107. {
  108. if (i == p)
  109. {
  110. std::swap(i, two[node].back());
  111. two[node].pop_back();
  112. break;
  113. }
  114. }
  115.  
  116. twoS[node] = 1;
  117. for (const int &i : two[node])
  118. {
  119. findTwoS(i, node);
  120. twoS[node] += twoS[i];
  121. }
  122. }
  123.  
  124. void update(int idx, int value)
  125. {
  126. if (idx == 0) return;
  127. for (int pos = idx ; pos <= n ; pos += pos & (-pos))
  128. {
  129. tree[pos] += value;
  130. }
  131. }
  132.  
  133. int query(int idx)
  134. {
  135. int res = 0;
  136. for (int pos = idx ; pos >= 1 ; pos -= pos & (-pos))
  137. {
  138. res += tree[pos];
  139. }
  140.  
  141. return res;
  142. }
  143.  
  144. int add[MAXN];
  145. void solve()
  146. {
  147. tourOne.push_back(0);
  148. tourTwo.push_back(0);
  149. buildTourOne(1, 0);
  150. for (int i = 1 ; i <= n ; ++i)
  151. {
  152. newNum[tourOne[i]] = i;
  153. }
  154.  
  155. for (int i = 1 ; i <= n ; ++i)
  156. {
  157. for (const int &j : oneBegin[i])
  158. {
  159. // std::cout << "edge: " << i << ' ' << j << ' ' << newNum[i] << ' ' << newNum[j] << '\n';
  160. one[newNum[i]].push_back(newNum[j]);
  161. }
  162.  
  163. for (const int &j : twoBegin[i])
  164. {
  165. two[newNum[i]].push_back(newNum[j]);
  166. }
  167. }
  168.  
  169. buildInOutTime(1, 0);
  170. findOneS(1, 0);
  171. findTwoS(1, 0);
  172.  
  173. for (int i = 1 ; i <= n ; ++i)
  174. {
  175. std::sort(two[i].begin(), two[i].end(), [&](int x, int y)
  176. {
  177. return twoS[x] < twoS[y];
  178. });
  179. }
  180.  
  181. timer = 1;
  182. buildTourTwo(1, 0);
  183.  
  184. for (int i = 1 ; i <= n ; ++i)
  185. {
  186. for (const int &j : one[i])
  187. {
  188. int size = n - oneS[j];
  189. int l = -1, r = two[i].size(), mid;
  190. while (l < r - 1)
  191. {
  192. mid = (l + r) / 2;
  193. if (n - twoS[two[i][mid]] >= size) l = mid;
  194. else r = mid;
  195. }
  196.  
  197. if (r < two[i].size())
  198. {
  199. int rr = outOne[j];
  200. int ll = inOne[j];
  201. queries[outTwo[i]].push_back({rr, j, '+'});
  202. queries[inTwo[two[i][r]] - 1].push_back({rr, j, '-'});
  203. queries[outTwo[i]].push_back({ll - 1, j, '-'});
  204. queries[inTwo[two[i][r]] - 1].push_back({ll - 1, j, '+'});
  205. }
  206.  
  207. if (twoS[i] < size)
  208. {
  209. queries[n].push_back({outOne[j], j, '+'});
  210. queries[n].push_back({inOne[j] - 1, j, '-'});
  211. queries[outTwo[i]].push_back({outOne[j], j, '-'});
  212. queries[inTwo[i] - 1].push_back({outOne[j], j, '+'});
  213. queries[outTwo[i]].push_back({inOne[j] - 1, j, '+'});
  214. queries[inTwo[i] - 1].push_back({inOne[j] - 1, j, '-'});
  215. }
  216. }
  217.  
  218. if (i == 1) continue;
  219. int size = oneS[i];
  220. int l = -1, r = two[i].size(), mid;
  221. while (l < r - 1)
  222. {
  223. mid = (l + r) / 2;
  224. if (n - twoS[two[i][mid]] >= size) l = mid;
  225. else r = mid;
  226. }
  227.  
  228. if (r < two[i].size())
  229. {
  230. queries[outTwo[i]].push_back({n, 1, '+'});
  231. queries[outTwo[i]].push_back({outOne[i], 1, '-'});
  232. queries[outTwo[i]].push_back({inOne[i] - 1, 1, '+'});
  233. queries[inTwo[two[i][r]] - 1].push_back({n, 1, '-'});
  234. queries[inTwo[two[i][r]] - 1].push_back({outOne[i], 1, '+'});
  235. queries[inTwo[two[i][r]] - 1].push_back({inOne[i] - 1, 1, '-'});
  236. }
  237.  
  238. if (twoS[i] < size)
  239. {
  240. queries[n].push_back({n, 1, '+'});
  241. queries[n].push_back({outOne[i], 1, '-'});
  242. queries[n].push_back({inOne[i] - 1, 1, '+'});
  243. queries[outTwo[i]].push_back({n, 1, '-'});
  244. queries[inTwo[i] - 1].push_back({n, 1, '+'});
  245. queries[outTwo[i]].push_back({outOne[i], 1, '+'});
  246. queries[outTwo[i]].push_back({inOne[i] - 1, 1, '-'});
  247. queries[inTwo[i] - 1].push_back({outOne[i], 1, '-'});
  248. queries[inTwo[i] - 1].push_back({inOne[i] - 1, 1, '+'});
  249. }
  250. }
  251.  
  252. for (int i = n ; i >= 1 ; --i)
  253. {
  254. for (const Query &curr : queries[i])
  255. {
  256. if (curr.type == '+') update(curr.idx, 1);
  257. else update(curr.idx, -1);
  258. }
  259.  
  260. add[tourTwo[i]] = query(n) - query(tourTwo[i] - 1);
  261. }
  262.  
  263. for (int i = 1 ; i <= n ; ++i)
  264. {
  265. ans[tourOne[i]] = add[i];
  266. }
  267. }
  268.  
  269. void output()
  270. {
  271. for (int i = 1 ; i <= n ; ++i)
  272. {
  273. std::cout << ans[i] << ' ';
  274. }
  275.  
  276. std::cout << '\n';
  277. }
  278.  
  279. void input()
  280. {
  281. int x, y;
  282. std::cin >> n;
  283. for (int i = 2 ; i <= n ; ++i)
  284. {
  285. std::cin >> x >> y;
  286. oneBegin[x].push_back(y);
  287. oneBegin[y].push_back(x);
  288. }
  289.  
  290. for (int i = 2 ; i <= n ; ++i)
  291. {
  292. std::cin >> x >> y;
  293. twoBegin[x].push_back(y);
  294. twoBegin[y].push_back(x);
  295. }
  296. }
  297.  
  298. void fastIO()
  299. {
  300. std::ios_base :: sync_with_stdio(0);
  301. std::cout.tie(nullptr);
  302. std::cin.tie(nullptr);
  303. }
  304.  
  305. int main()
  306. {
  307. fastIO();
  308. input();
  309. solve();
  310. output();
  311.  
  312. return 0;
  313. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement