[国家集训队] Crash 的文明世界
考虑 次方十分的难受,我们考虑用第二类斯特林数转化一下。考虑经典式子:
我们有:
考虑求后面那坨,我们设 表示 的子树中所有节点的 的和,对于 的每个儿子,它子树中的点到 的距离比到它的距离大 ,由加法公式:
我们要求每一个点为根时的 ,换根即可。
#include <bits/stdc++.h>
using namespace std;
const int N = 5e4 + 5, mod = 10007;
int f[N][155], S[505][505], ans[N][155], fac[155];
struct edge {
int head, to, nxt;
} ed[N << 1];
int en = 0, n, k;
inline void addedge(int from, int to) {
ed[++en].to = to; ed[en].to = to; ed[en].nxt = ed[from].head; ed[from].head = en;
}
inline void dfs(int now, int fa) {
f[now][0] = 1;
for (int i = ed[now].head; i; i = ed[i].nxt) {
int v = ed[i].to;
if (v == fa) continue;
dfs(v, now);
f[now][0] = (f[now][0] + f[v][0]) % mod;
for (int j = 1; j <= k; ++j)
f[now][j] = (f[now][j] + f[v][j] + f[v][j - 1]) % mod;
}
}
inline void dfs2(int now, int fa) {
for (int i = 0; i <= k; ++i) ans[now][i] = f[now][i];
for (int i = ed[now].head; i; i = ed[i].nxt) {
int v = ed[i].to;
if (v == fa) continue;
f[now][0] -= f[v][0];
if (f[now][0] < 0) f[now][0] += mod;
for (int j = 1; j <= k; ++j) {
f[now][j] -= f[v][j] + f[v][j - 1];
f[now][j] %= mod;
if (f[now][j] < 0) f[now][j] += mod;
}
f[v][0] += f[now][0];
if (f[v][0] >= mod) f[v][0] -= mod;
for (int j = 1; j <= k; ++j)
f[v][j] = (f[v][j] + f[now][j] + f[now][j - 1]) % mod;
dfs2(v, now);
f[v][0] -= f[now][0];
if (f[v][0] < 0) f[v][0] += mod;
for (int j = 1; j <= k; ++j) {
f[v][j] = (f[v][j] - f[now][j] - f[now][j - 1]) % mod;
if (f[v][j] < 0) f[v][j] += mod;
}
f[now][0] += f[v][0];
if (f[now][0] >= mod) f[now][0] -= mod;
for (int j = 1; j <= k; ++j)
f[now][j] = (f[now][j] + f[v][j] + f[v][j - 1]) % mod;
}
}
inline int read() {
register int s = 0; register char ch = getchar();
while (!isdigit(ch)) ch = getchar();
while (isdigit(ch)) s = (s << 1) + (s << 3) + (ch & 15), ch = getchar();
return s;
}
int main() {
n = read(); k = read();
fac[0] = 1;
for (int i = 1; i <= k; ++i) fac[i] = (1ll * i * fac[i - 1]) % mod;
for (int i = 1, u, v; i < n; ++i) {
u = read(); v = read();
addedge(u, v); addedge(v, u);
} dfs(1, 0); dfs2(1, 0);
S[0][0] = 1;
for (int i = 1; i <= k; ++i) {
S[i][0] = 0;
for (int j = 1; j <= k; ++j)
S[i][j] = (S[i - 1][j - 1] + j * S[i - 1][j]) % mod;
}
for (int i = 1; i <= n; ++i) {
int as = 0;
for (int j = 0; j <= k; ++j) {
as += (1ll * ((1ll * S[k][j] * fac[j]) % mod) * ans[i][j]) % mod;
if (as >= mod) as -= mod;
} printf("%d\n", as);
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现