社区讨论
SOS
P14637[NOIP2025] 树的价值参与者 2已保存回复 1
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 1 条
- 当前快照
- 1 份
- 快照标识符
- @mk8b0f1b
- 此快照首次捕获于
- 2026/01/10 20:51 上个月
- 此快照最后确认于
- 2026/01/13 22:20 上个月
CPP
#include <bits/stdc++.h>
using namespace std;
const long long INF = 1e18;
void solve() {
int n, m;
cin >> n >> m;
vector<vector<int>> g(n + 1);
for (int i = 2; i <= n; i++) {
int p;
cin >> p;
g[p].push_back(i);
}
vector<int> sz(n + 1), depth(n + 1), lim(n + 1);
function<void(int)> dfs_sz = [&](int u) {
sz[u] = 1;
for (int v : g[u]) {
depth[v] = depth[u] + 1;
dfs_sz(v);
sz[u] += sz[v];
}
// lim[u] 表示以 u 为根的子树中,可能的最大 mex 值(受子树大小和深度限制)
lim[u] = min(sz[u], m - depth[u] + 1);
// 由于深度不超过 m,所以 m - depth[u] + 1 >= 1,因此 lim[u] >= 1
// 但为了安全,我们确保 lim[u] 至少为 0
if (lim[u] < 0) lim[u] = 0;
};
depth[1] = 0;
dfs_sz(1);
vector<vector<long long>> f(n + 1);
function<void(int)> dfs = [&](int u) {
if (g[u].empty()) {
f[u].assign(lim[u] + 1, -INF);
f[u][0] = 0;
if (lim[u] >= 1) f[u][1] = 1;
return;
}
for (int v : g[u]) {
dfs(v);
}
long long sum0 = 0;
for (int v : g[u]) {
sum0 += f[v][0];
}
f[u].assign(lim[u] + 1, -INF);
// 情况1:所有子节点的 mex 都为 0
for (int i = 0; i <= lim[u]; i++) {
// 需要满足子树大小足够容纳 i 个不同的权值
if (i <= sz[u]) {
f[u][i] = i + sum0;
}
}
// 情况2:恰好一个子节点的 mex 大于 0
for (int v : g[u]) {
// 预处理 val[j] = sum0 - f[v][0] + f[v][j]
vector<long long> val(lim[v] + 1, -INF);
for (int j = 0; j <= lim[v]; j++) {
if (f[v][j] > -INF / 2) {
val[j] = sum0 - f[v][0] + f[v][j];
}
}
// 对于每个 j(j>0),更新对应的 i 区间
for (int j = 1; j <= lim[v]; j++) {
if (val[j] < -INF / 2) continue;
int left = j;
int right = min(lim[u], j + sz[u] - sz[v]);
if (left > right) continue;
// 直接更新区间内的每个 i
for (int i = left; i <= right; i++) {
long long cand = i + val[j];
if (cand > f[u][i]) {
f[u][i] = cand;
}
}
}
}
// 释放子节点的内存,避免 MLE
for (int v : g[u]) {
vector<long long>().swap(f[v]);
}
};
dfs(1);
long long ans = 0;
for (int i = 0; i <= lim[1]; i++) {
if (f[1][i] > ans) ans = f[1][i];
}
cout << ans << "\n";
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
int t;
cin >> t;
while (t--) {
solve();
}
return 0;
}
回复
共 1 条回复,欢迎继续交流。
正在加载回复...