Advertisement
pb_jiang

CF600E

Nov 1st, 2023
843
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.58 KB | None | 0 0
  1. // Problem: E. Lomsat gelral
  2. // Contest: Codeforces - Educational Codeforces Round 2
  3. // URL: https://codeforces.com/problemset/problem/600/E
  4. // Memory Limit: 256 MB
  5. // Time Limit: 2000 ms
  6. //
  7. // Powered by CP Editor (https://cpeditor.org)
  8.  
  9. #include <assert.h>
  10. #include <bits/stdc++.h>
  11. using namespace std;
  12. #ifndef __DEBUG__
  13. #define dbg(...) 42
  14. #endif
  15. template <class T> using mpq = priority_queue<T, vector<T>, greater<T>>;
  16.  
  17. using ll = long long;
  18. using pii = pair<int, int>;
  19. using pll = pair<ll, ll>;
  20. using vl = vector<ll>;
  21. using vi = vector<int>;
  22. using a2l = array<ll, 2>;
  23.  
  24. #if 0
  25. // 启发式合并
  26. int main(int argc, char **argv)
  27. {
  28.     int n, x, y;
  29.     cin >> n;
  30.     vi vc(n + 1);
  31.     for (int i = 1; i <= n; ++i)
  32.         cin >> vc[i];
  33.     vector<vi> g(n + 1);
  34.     for (int i = 1; i < n; ++i)
  35.         cin >> x >> y, g[x].push_back(y), g[y].push_back(x);
  36.     vl ans(n + 1);
  37.     vi dl(n + 1), dr(n + 1), dv(n + 1);
  38.     vi dson(n + 1), dsize(n + 1);
  39.     int cur_cnt = 0;
  40.     function<int(int, int)> dfs_cnt = [&](int u, int fa) {
  41.         int ret = 1, son_id = 0, son_cnt = 0;
  42.         dl[u] = cur_cnt++;
  43.         dv[dl[u]] = u;
  44.         for (auto v : g[u]) {
  45.             if (v == fa)
  46.                 continue;
  47.             int sub_cnt = dfs_cnt(v, u);
  48.             if (sub_cnt > son_cnt)
  49.                 son_cnt = sub_cnt, son_id = v;
  50.             ret += sub_cnt;
  51.         }
  52.         dr[u] = cur_cnt;
  53.         dson[u] = son_id;
  54.         return dsize[u] = ret;
  55.     };
  56.     dfs_cnt(1, -1);
  57.  
  58.     vi ccnt(n + 1);
  59.     ll accumulated_color_score = 0;
  60.     int max_appearance = -1;
  61.     auto inc_color_cnt = [&](int u) -> ll {
  62.         auto &c = ccnt[vc[u]];
  63.         c++;
  64.         if (c > max_appearance) {
  65.             max_appearance = c;
  66.             accumulated_color_score = vc[u];
  67.         } else if (c == max_appearance) {
  68.             accumulated_color_score += vc[u];
  69.         }
  70.         return accumulated_color_score;
  71.     };
  72.     auto clear_color_cnt = [&]() {
  73.         accumulated_color_score = 0;
  74.         max_appearance = -1;
  75.     };
  76.     function<void(int, int, int)> dfs = [&](int u, int pa, int persist) {
  77.         for (auto v : g[u]) {
  78.             if (v == pa || v == dson[u])
  79.                 continue;
  80.             dfs(v, u, 0);
  81.         }
  82.         if (dson[u])
  83.             dfs(dson[u], u, 1);
  84.  
  85.         for (auto v : g[u]) {
  86.             if (v == pa || v == dson[u])
  87.                 continue;
  88.             for (int k = dl[v]; k < dr[v]; ++k)
  89.                 inc_color_cnt(dv[k]);
  90.         }
  91.         ans[u] = inc_color_cnt(u);
  92.  
  93.         if (persist == 0) {
  94.             for (int k = dl[u]; k < dr[u]; ++k)
  95.                 ccnt[vc[dv[k]]]--;
  96.             clear_color_cnt();
  97.         }
  98.     };
  99.     dfs(1, -1, 1);
  100.     for (int i = 1; i <= n; ++i)
  101.         cout << ans[i] << ' ';
  102.     cout << endl;
  103.     return 0;
  104. };
  105. #else
  106. // 线段树
  107. struct SegTree {
  108.     struct NodeInfo {
  109.         ll acc, max_freq;
  110.         NodeInfo operator+(const NodeInfo &n) const
  111.         {
  112.             NodeInfo ret{0ll, 0ll};
  113.             if (max_freq < n.max_freq)
  114.                 ret = n;
  115.             else if (max_freq == n.max_freq)
  116.                 ret = NodeInfo{acc + n.acc, max_freq};
  117.             else
  118.                 ret = *this;
  119.             return ret;
  120.         };
  121.     };
  122.     int ncnt;
  123.     vi root, ls, rs;
  124.     vector<NodeInfo> tr;
  125.     SegTree(int n) : ncnt(1)
  126.     {
  127.         root = vi(n);
  128.         ls = rs = vi(n << 5);
  129.         tr = vector<NodeInfo>(n << 5, NodeInfo{0ll, 0ll});
  130.     }
  131.     void popup(int rt) { tr[rt] = tr[ls[rt]] + tr[rs[rt]]; }
  132.     void update(int &rt, int pos, int l, int r)
  133.     {
  134.         if (rt == 0)
  135.             rt = ncnt++;
  136.         if (l == r) {
  137.             tr[rt].acc = pos;
  138.             tr[rt].max_freq++;
  139.             return;
  140.         }
  141.         int mid = l + r >> 1;
  142.         if (pos <= mid)
  143.             update(ls[rt], pos, l, mid);
  144.         else
  145.             update(rs[rt], pos, mid + 1, r);
  146.         popup(rt);
  147.     }
  148.     int merge(int rt1, int rt2, int l, int r) // merge rt2 into rt1
  149.     {
  150.         if (rt1 == 0 || rt2 == 0)
  151.             return rt1 + rt2;
  152.         if (l == r) {
  153.             tr[rt1].max_freq += tr[rt2].max_freq;
  154.             return rt1;
  155.         }
  156.         int mid = l + r >> 1;
  157.         ls[rt1] = merge(ls[rt1], ls[rt2], l, mid);
  158.         rs[rt1] = merge(rs[rt1], rs[rt2], mid + 1, r);
  159.         popup(rt1);
  160.         return rt1;
  161.     }
  162.     void out(int rt1, int l, int r, int lvl)
  163.     {
  164.         for (int i = 0; i < lvl; ++i)
  165.             cerr << ' ';
  166.         fprintf(stderr, "%d:%d~%d:%lld,%lld\n", rt1, l, r, tr[rt1].acc, tr[rt1].max_freq);
  167.         int mid = l + r >> 1;
  168.         if (l != r) {
  169.             out(ls[rt1], l, mid, lvl + 1);
  170.             out(rs[rt1], mid + 1, r, lvl + 1);
  171.         }
  172.     }
  173. };
  174. int main(int argc, char **argv)
  175. {
  176.     int n, x, y;
  177.     cin >> n;
  178.     vi vc(n + 1);
  179.     for (int i = 1; i <= n; ++i)
  180.         cin >> vc[i];
  181.     vector<vi> g(n + 1);
  182.     for (int i = 1; i < n; ++i)
  183.         cin >> x >> y, g[x].push_back(y), g[y].push_back(x);
  184.     vl ans(n + 1);
  185.     SegTree seg(n + 1);
  186.     function<void(int, int)> dfs = [&](int u, int fa) {
  187.         for (auto v : g[u]) {
  188.             if (v == fa)
  189.                 continue;
  190.             dfs(v, u);
  191.             seg.root[u] = seg.merge(seg.root[u], seg.root[v], 1, n);
  192.         }
  193.         seg.update(seg.root[u], vc[u], 1, n);
  194.         // dbg("insert ", u, vc[u]);
  195.         ans[u] = seg.tr[seg.root[u]].acc;
  196.         // seg.out(seg.root[u], 1, n, 0);
  197.         // cerr << endl;
  198.     };
  199.     dfs(1, -1);
  200.     for (int i = 1; i <= n; ++i)
  201.         cout << ans[i] << ' ';
  202.     cout << endl;
  203. };
  204. #endif
  205.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement