题意
传送门
给一棵树
求每个点。对10007取模。
思路
已知:
直接推答案柿子:
因此可以通过组合数递推,反推到树上dp递推(距离减一不就是儿子的状态吗),存状态为子树内,所有点对贡献的贡献和。
递推柿很简洁:
含义为:所有点到贡献可以划分为所有点到贡献。
因此想要把数学推理到dp上来,就要了解这个抽象的数学柿子表达的什么意思。
code
点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int N=5e4+5;
const int M=155;
const int mod=10007;
int jc[N],S[M][M],n,K;
int dp[N][M],nxt[N<<1],to[N<<1],head[N],ecnt;
void add_edge(int u,int v) {nxt[++ecnt]=head[u];to[ecnt]=v;head[u]=ecnt;}
void dfs1(int u,int fa) {
dp[u][0]=1;
for(int i=head[u];i;i=nxt[i]) {
int v=to[i];if(v==fa)continue;
dfs1(v,u);
for(int j=1;j<=K;j++) {dp[u][j]=(dp[u][j]+dp[v][j]+dp[v][j-1])%mod;}
dp[u][0]=(dp[u][0]+dp[v][0])%mod;
}
}
int ans[N];
void dfs2(int u,int fa) {
int tmp[M];
for(int j=0;j<=K;j++) {ans[u]=(ans[u]+S[K][j]*jc[j]%mod*dp[u][j])%mod;tmp[j]=dp[u][j];}
for(int i=head[u];i;i=nxt[i]) {
int v=to[i];if(v==fa)continue;
for(int j=1;j<=K;j++) {dp[u][j]=(dp[u][j]-dp[v][j]-dp[v][j-1])%mod;}
dp[u][0]=(dp[u][0]-dp[v][0])%mod;
for(int j=1;j<=K;j++) {dp[v][j]=(dp[v][j]+dp[u][j]+dp[u][j-1])%mod;}
dp[v][0]=(dp[v][0]+dp[u][0])%mod;
dfs2(v,u);
for(int j=0;j<=K;j++) dp[u][j]=tmp[j];
}
}
void init() {
S[0][0]=1;
for(int i=1;i<=K;i++) {
S[i][0]=0;
for(int j=1;j<=i;j++) {
S[i][j]=(S[i-1][j-1]+j*S[i-1][j])%mod;
}
}
jc[0]=1;for(int i=1;i<=n;i++)jc[i]=jc[i-1]*i%mod;
}
int main() {
scanf("%d%d",&n,&K);
init();
for(int i=1;i<n;i++) {int u,v;scanf("%d%d",&u,&v);add_edge(u,v),add_edge(v,u);}
dfs1(1,0),dfs2(1,0);
for(int i=1;i<=n;i++) {printf("%d\n",(ans[i]+mod)%mod);}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人