libobil

Untitled

Oct 5th, 2023
49
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 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. }
Add Comment
Please, Sign In to add comment