Description

给定一棵 \(n\) 个点的树,对于每个点 \(i\) 求 \(S(i)=\sum\limits_{j=1}^n \operatorname{dist(i,j)}^k\) 。\(n\leq 50000,k\leq 150\)。

Sol

根据斯特林展开,原式化为

\[\begin{align}S(i)= & \sum\limits_{j=1}^n \sum\limits_{p=0}^k S(k,p)\cdot \dbinom{\operatorname{dist(i,j)}}{p} \cdot p! \nonumber \\ = & \sum_{p=0}^kS(k,p)\cdot p!\cdot\sum_{j=1}^n\dbinom{\operatorname{dist(i,j)}}{p} \nonumber \end{align}
\]

这个式子启发我们对于每个点 \(i\) 和每个 \(p\) ,维护好 \(\sum\limits_{j=1}^n \dbinom{\operatorname{dist(i,j)}}p\) 就好了

又因为 \(\dbinom{n}{m}=\dbinom{n-1}{m-1}+\dbinom{n-1}{m}\) ,所以设 \(dp[i][p]=\sum\limits_{j=1}^n \dbinom{\operatorname{dist(i,j)}}p\) ,这样就可以递推了。

先做一遍树形\(\text{DP}\)求出每个点子树的\(\mathrm{dp}\)值,再换根一下求出子树外的\(\text{dp}\)值就行了。

复杂度 \(O(nk)\)。

Code

#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
typedef double db;
typedef long long ll;
const int K=155;
const int N=50005;
const int mod=10007; int dp[N][K],f[K];
int fac[N],S[K][K];
int n,k,cnt,head[N]; struct Edge{
int to,nxt;
}edge[N<<1]; void add(int x,int y){
edge[++cnt].to=y;
edge[cnt].nxt=head[x];
head[x]=cnt;
} void init(int n,int m){
fac[0]=1;
for(int i=1;i<=n;i++) fac[i]=1ll*fac[i-1]*i%mod;
S[0][0]=1;
for(int i=1;i<=K;i++)
for(int j=1;j<=i;j++)
S[i][j]=(S[i-1][j-1]+1ll*S[i-1][j]*j%mod)%mod;
} void dfs(int now,int fa=0){
dp[now][0]=1;
for(int i=head[now];i;i=edge[i].nxt){
int to=edge[i].to;
if(to==fa) continue;
dfs(to,now);
(dp[now][0]+=dp[to][0])%=mod;
for(int j=1;j<=k;j++)
(dp[now][j]+=dp[to][j-1]+dp[to][j])%=mod;
}
} void dfs2(int now,int fa=0){
if(fa){
f[0]=dp[now][0];
(dp[fa][0]-=dp[now][0]-mod)%=mod;
for(int j=1;j<=k;j++)
(dp[fa][j]-=dp[now][j-1]+dp[now][j]-mod-mod)%=mod,f[j]=dp[now][j];
(dp[now][0]+=dp[fa][0])%=mod;
for(int j=1;j<=k;j++)
(dp[now][j]+=dp[fa][j-1]+dp[fa][j])%=mod;
(dp[fa][0]+=f[0])%=mod;
for(int j=1;j<=k;j++)
(dp[fa][j]+=f[j]+f[j-1])%=mod;
}
for(int i=head[now];i;i=edge[i].nxt){
int to=edge[i].to;
if(to==fa) continue;
dfs2(to,now);
}
} signed main(){
init(N-5,K-5);
scanf("%d%d",&n,&k);
for(int x,y,i=1;i<n;i++)
scanf("%d%d",&x,&y),add(x,y),add(y,x);
dfs(1); dfs2(1);
for(int i=1;i<=n;i++){
int ans=0;
for(int j=0;j<=k;j++)
(ans+=1ll*S[k][j]%mod*fac[j]%mod*dp[i][j]%mod)%=mod;
printf("%d\n",ans);
} return 0;
}

[国家集训队] Crash的文明世界的更多相关文章

  1. [国家集训队] Crash 的文明世界(第二类斯特林数)

    题目 [国家集训队] Crash 的文明世界 前置 斯特林数\(\Longrightarrow\)斯特林数及反演总结 做法 \[\begin{aligned} ans_x&=\sum\limi ...

  2. [国家集训队] Crash 的文明世界

    不错的树形$ DP$的题 可为什么我自带大常数啊$ cry$ 链接:here 题意:给定一棵$ n$个节点的树,边权为$ 1$,对于每个点$ x$求$ \sum\limits_{i=1}^n dist ...

  3. 洛谷P4827 [国家集训队] Crash 的文明世界 [斯特林数,组合数,DP]

    传送门 思路 又见到这个\(k\)次方啦!按照套路,我们将它搞成斯特林数: \[ ans_x=\sum_{i=0}^k i!S(k,i)\sum_y {dis(x,y) \choose i} \] 前 ...

  4. P4827 [国家集训队] Crash 的文明世界

    传送门:洛谷 题目大意:设$$S(i)=\sum_{j=1}^ndis(i,j)^k$$,求$S(1),S(2),\ldots,S(n)$. 数据范围:$n\leq 50000,k\leq 150$ ...

  5. 解题:国家集训队 Crash 的文明世界

    题面 这种套着高次幂的统计问题一般都要用到第二类斯特林数和自然数幂的关系:$a^k=\sum\limits_{i=0}^{k}S_k^iC_a^i*i!$ 那么对于每个点$x$有: $ans_x=\s ...

  6. 【[国家集训队] Crash 的文明世界】

    先写一个五十分的思路吧 首先这道题有一个弱化版 [POI2008]STA-Station 相当于\(k=1\),于是就是一个非常简单的树形\(dp\)的\(up\ \ and\ \ down\)思想 ...

  7. P4827 [国家集训队] Crash 的文明世界(第二类斯特林数+树形dp)

    传送门 对于点\(u\),所求为\[\sum_{i=1}^ndis(i,u)^k\] 把后面那堆东西化成第二类斯特林数,有\[\sum_{i=1}^n\sum_{j=0}^kS(k,j)\times ...

  8. 国家集训队 Crash 的文明世界(第二类斯特林数+换根dp)

    题意 ​ 题目链接:https://www.luogu.org/problem/P4827 ​ 给定一棵 \(n\) 个节点的树和一个常数 \(k\) ,对于树上的每一个节点 \(i\) ,求出 \( ...

  9. 洛谷 P4827 [国家集训队] Crash 的文明世界

    题目描述 ​ 给你一棵 n 个点的树,对于树上的每个节点 i,求 \(\sum_{j=1}^ndis(i,j)^k\).其中 \(dis(i,j)\) 为两点在树上的距离. 输入格式 ​ 第一行两个整 ...

随机推荐

  1. Kubernetes中的RBAC

    Kubernetes中,授权有ABAC(基于属性的访问控制).RBAC(基于角色的访问控制).Webhook.Node.AlwaysDeny(一直拒绝)和AlwaysAllow(一直允许)这6种模式. ...

  2. 图解Raft之领导者选举

    图解Raft领导者选举,这里通过五张图来解答Raft选举的全过程: Raft集群各个节点之间是通过RPC通讯传递消息的,每个节点都包含一个RPC服务端与客户端,初始时启动RPC服务端.状态设置为Fol ...

  3. Linux yun命令使用报错:File "/usr/bin/yum", line 30 except KeyboardInterrupt, e:

    原文参考:https://www.cnblogs.com/caiji/p/7891923.html 使用yum更新perl源,报错 问题出现原因: yum包管理是使用python2.x写的,将pyth ...

  4. 马昕璐 201771010118《面向对象程序设计(java)》第十八周学习总结

    实验十八  总复习 实验时间 2018-12-30 1.实验目的与要求 (1) 综合掌握java基本程序结构: (2) 综合掌握java面向对象程序设计特点: (3) 综合掌握java GUI 程序设 ...

  5. 使用COOKIE实现登录 VS 使用SESSION实现登录

    注:本文使用的代码基于PHP,其他语言逻辑同理. 一:使用COOKIE实现登录验证 使用cookie实现登录的方式,主要通过一些单向的加密信息进行验证.比如admin用户登录了之后,服务端生成一个co ...

  6. 下载 mysql 数据库 的步骤 完整版

    1. 官网(点这里)上下载 2. 3. 4. 5. 6. 7.

  7. Python基础之自定义工具类

    class ListHelper: @staticmethod def find_all(target, func_condition): """ 查找列表中满足条件的所 ...

  8. [安卓] 20、基于蓝牙BLE的广播包高频快速搜索

    前言: 之前介绍过很多蓝牙beacon.搜索.连接.通讯的文章.不过最近我发现:之前写的蓝牙广播包搜索的工程,搜索频率太慢,而且不能一直保持搜索状态.因此,这里探讨下高频蓝牙广播包扫描 -- 蓝牙BL ...

  9. 如何让浏览器支持ES6语法,步骤详细到小学生都能看懂!

    为什么ES6会有兼容性问题? 由于广大用户使用的浏览器版本在发布的时候也许早于ES6的定稿和发布,而到了今天,我们在编程中如果使用了ES6的新特性,浏览器若没有更新版本,或者新版本中没有对ES6的特性 ...

  10. Java中的锁——Lock和synchronized

    上一篇Java中的队列同步器AQS 一.Lock接口 1.Lock接口和synchronized内置锁 a)synchronized:Java提供的内置锁机制,Java中的每个对象都可以用作一个实现同 ...