codeforces600E. Lomsat gelral(dsu on tree笔记)

知识前驱:树链剖分

codeforces600E. Lomsat gelral

题意:给出一个树,求出每个节点的子树中出现次数最多的颜色的编号和

分析:递归求解,对于一棵树,求出他的所有子树的颜色编号次数加上它本身,找到最大即是它的答案。对于他的兄弟来说,应该将计数器清0并同过程求解,在最后一个兄弟计算完毕后,此时计数器可不清0,再次统计该兄弟的兄弟(即该兄弟的同深度其他节点),便求出了它的父亲的所有子树的颜色编号次数,再加上它本身,找到最大即是它父亲的答案。

dsu on tree在这样一个暴力的过程中,将重儿子作为上述的最后一个兄弟,此时计数器不清0,再暴力统计轻儿子以获得答案。

 1 #pragma GCC optimize(3, "Ofast", "inline")
 2  
 3 #include <bits/stdc++.h>
 4  
 5 #define start ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
 6 #define ll long long
 7 #define LL long long
 8 #define uu unsigned int
 9 #define int ll
10 #define ls st<<1
11 #define rs st<<1|1
12 using namespace std;
13 const int maxn = (ll) 1e6 + 5;
14 const int mod = 1000000007;
15 const int inf = 0x3f3f3f3f;
16  
17 int son[maxn], siz[maxn], cnt[maxn], col[maxn], ans[maxn];
18 vector<int> v[maxn];
19  
20 void dfs(int x, int pre) {
21     siz[x] = 1;
22     for (auto &to:v[x]) {
23         if (to == pre)
24             continue;
25         dfs(to, x);
26         siz[x] += siz[to];
27         if (siz[to] > siz[son[x]])
28             son[x] = to;
29     }
30 }
31  
32 int sum, maxx, now;
33  
34 void add(int x, int pre, int val) {
35     cnt[col[x]] += val;
36     if (cnt[col[x]] > maxx) {
37         maxx = cnt[col[x]];
38         sum = col[x];
39     } else if (cnt[col[x]] == maxx)
40         sum += col[x];
41     for (auto &to:v[x]) {
42         if (to == now || to == pre)
43             continue;
44         add(to, x, val);
45     }
46 }
47  
48 void dfs2(int x, int pre, bool ord) {
49     for (auto &to:v[x]) {
50         if (to == pre || to == son[x])
51             continue;
52         dfs2(to, x, false);
53     }
54     if (son[x]) {
55         dfs2(son[x], x, true);
56         now = son[x];
57     }
58     add(x, pre, 1);
59     ans[x] = sum;
60     if (!ord) {
61         now = 0;
62         add(x, pre, -1);
63         sum = 0;
64         maxx = 0;
65     }
66 }
67  
68 signed main() {
69     start;
70     int n;
71     cin >> n;
72     for (int i = 1; i <= n; ++i)
73         cin >> col[i];
74     for (int i = 1; i < n; ++i) {
75         int x, y;
76         cin >> x >> y;
77         v[x].push_back(y);
78         v[y].push_back(x);
79     }
80     dfs(1, 0);
81     dfs2(1, 0, 0);
82     for (int i = 1; i <= n; ++i)
83         cout << ans[i] << ' ';
84     return 0;
85 }
原文地址:https://www.cnblogs.com/F-Mu/p/11456220.html