Codeforces 1606F. Tree Queries
Codeforces 1606F. Tree Queries
对于询问 , 发现答案一定在 内. 注意到这个 , 可以考虑根号分治.
- 可以直接树上背包预处理出答案数组 . 转移时考虑每个儿子是否删掉, 转移方程为 . 该部分的时空复杂度均为 .
- 此时一定有 . 于是我们可以预处理出 表示对于节点 , 其子树内删除 个点之后的最大儿子数. 转移时按照树形背包的方式, 考虑每个儿子是否删掉, 状态转移方程为 . 由于树形背包的时间复杂度为 , 该部分的时空复杂度均为 .
于是总时间复杂度为 . 可以通过.
注意到如果开两个数组 会爆空间, 于是重复利用即可.
参考代码
#include <bits/stdc++.h>
using namespace std;
template<typename _Tp> _Tp &min_eq(_Tp &x, const _Tp &y) { return x = min(x, y); }
template<typename _Tp> _Tp &max_eq(_Tp &x, const _Tp &y) { return x = max(x, y); }
static constexpr int inf = 0x3f3f3f3f;
static constexpr int Maxn = 2e5 + 5;
static constexpr int BLOCK = 500;
int n, q, blk;
vector<int> g[Maxn];
int qv[Maxn], qk[Maxn];
int ans[Maxn];
int f[Maxn][BLOCK];
void dfs1(int u, int fa) {
for (int j = 0; j <= blk; ++j)
f[u][j] = 0;
for (const int &v: g[u]) if (v != fa) {
dfs1(v, u);
for (int j = 0; j <= blk; ++j) {
f[u][j] = max(f[u][j] + 1, f[u][j] + f[v][j] - j);
}
}
} // dfs1
int sz[Maxn];
void dfs2(int u, int fa) {
for (int i = 0; i <= blk; ++i)
f[u][i] = -inf;
f[u][0] = 0;
sz[u] = 1;
for (const int &v: g[u]) if (v != fa) {
dfs2(v, u);
static int g[BLOCK];
for (int i = 0; i <= sz[u] + sz[v] && i <= blk; ++i)
g[i] = -inf;
for (int i = 0; i <= sz[u] && i <= blk; ++i)
for (int j = 0; j <= sz[v] && i + j <= blk; ++j) {
max_eq(g[i + j], f[u][i] + 1);
max_eq(g[i + j + 1], f[u][i] + f[v][j]);
}
for (int i = 0; i <= sz[u] + sz[v] && i <= blk; ++i)
f[u][i] = g[i];
sz[u] += sz[v];
}
} // dfs2
int main(void) {
scanf("%d", &n);
blk = (int)sqrt(n);
for (int i = 1; i <= n - 1; ++i) {
int u, v;
scanf("%d%d", &u, &v);
g[u].push_back(v);
g[v].push_back(u);
}
scanf("%d", &q);
for (int i = 1; i <= q; ++i)
scanf("%d%d", &qv[i], &qk[i]);
memset(ans, 0, sizeof(ans));
dfs1(1, 0);
for (int i = 1; i <= q; ++i)
if (qk[i] <= blk)
ans[i] = f[qv[i]][qk[i]];
dfs2(1, 0);
for (int i = 1; i <= q; ++i)
if (qk[i] > blk) {
for (int j = 0; j <= blk; ++j) {
max_eq(ans[i], f[qv[i]][j] - qk[i] * j);
}
}
for (int i = 1; i <= q; ++i)
printf("%d\n", ans[i]);
exit(EXIT_SUCCESS);
} // main
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】