我感觉我树上启发式合并写的挺标准的,为什么过不了~
求大佬帮忙看看:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 100010;
int n, m, sz[maxn], c[maxn], cnt[maxn];
bool big[maxn];
vector<int> g[maxn];
/**
res[u] 表示 u 对应的答案
ap[i] 表示目前出现次数等于i的颜色编号和
apid 表示目前出现次数最多的颜色的出现次数
*/
long long res[maxn], ap[maxn];
int apid;
void add(int u, int p, int x) {
int cc = cnt[ c[u] ];
ap[cc] -= c[u];
ap[cc+x] += c[u];
if (x > 0 && apid < cc+x) apid = cc+x;
if (x < 0 && cc == apid && ap[cc] == 0) apid --;
cnt[ c[u] ] += x;
for (vector<int>::iterator it = g[u].begin(); it != g[u].end(); it ++) {
int v = *it;
if (v != p && !big[v])
add(v, u, x);
}
}
void dfs(int u, int p, bool keep) {
int mx = -1, bigSon = -1; // mx表示重儿子的sz, bigSon表示重儿子编号
for (vector<int>::iterator it = g[u].begin(); it != g[u].end(); it ++) {
int v = *it;
if (v != p && sz[v] > mx)
mx = sz[ bigSon = v ];
}
for (vector<int>::iterator it = g[u].begin(); it != g[u].end(); it ++) {
int v = *it;
if (v != p && v != bigSon)
dfs(v, u, false);
}
if (bigSon != -1)
dfs(bigSon, u, true),
big[bigSon] = true;
add(u, p, 1);
res[u] = ap[apid];
if (bigSon != -1)
big[bigSon] = 0;
if (!keep)
add(u, p, -1);
}
int main() {
scanf("%d", &n);
for (int i = 1; i <= n; i ++) scanf("%d", c+i);
for (int i = 1; i < n; i ++) {
int a, b;
scanf("%d%d", &a, &b);
g[a].push_back(b);
g[b].push_back(a);
}
dfs(1, -1, false);
for (int i = 1; i <= n; i ++) printf("%d ", res[i]);
return 0;
}