题目传送门

题目大意

给出一个\(n\)个点的树,和常数\(k\),对于\(\forall i\in[1,n]\),求出:

\[\sum_{j=1}^{n} \text{dist}(i,j)^k
\]

\(n\le 5\times 10^4,k\le 150\)

思路

真的很妙,一开始完全没有思路,看了\(\texttt{y2823774827y}\)的题解之后瞬间懂了。

我们考虑对于\(i\)如何计算答案,我们发现这个指数非常不好看,于是我们可以使用第二类斯特林数展开,就跟组合数问题差不多的,变为:

\[\sum_{j=1}^{n}\sum_{d=0}^{\text{dist}(i,j)}\binom{\text{dist}(i,j)}{d}\begin{Bmatrix}k\\d\end{Bmatrix}d!
\]

交换求和顺序可以得到:

\[=\sum_{d=0}^{\min(n,k)}\begin{Bmatrix}k\\d\end{Bmatrix}d!\sum_{j=1}^{n}\binom{\text{dist}(i,j)}{d}
\]

于是,我们的问题就是如何快速求出后面那个\(\sum\)。我们想到这个东西可以拆成:

\[\binom{\text{dist}(i,j)}{d}=\binom{\text{dist}(i,j)-1}{d}+\binom{\text{dist}(i,j)-1}{d-1}
\]

于是,我们用换根\(dp\)解决这个问题了。具体见代码。

\(\texttt{Code}\)

#include <bits/stdc++.h>
using namespace std; #define Int register int
#define MAXN 50005
#define mod 10007
#define MAXM 155 int qkpow (int a,int b){
int res = 1;for (;b;b >>= 1,a = 1ll * a * a % mod) if (b & 1) res = 1ll * res * a % mod;
return res;
} int mul (int a,int b){return 1ll * a * b % mod;}
int dec (int a,int b){return a >= b ? a - b : a + mod - b;}
int add (int a,int b){return a + b >= mod ? a + b - mod : a + b;} struct edge{
int v,nxt;
}e[MAXN << 1]; int top = 1,head[MAXN]; void Add_Edge (int u,int v){
e[++ top] = edge {v,head[u]},head[u] = top;
e[++ top] = edge {u,head[v]},head[v] = top;
} int n,k,S[MAXM][MAXM],fac[MAXM],dp1[MAXN][MAXM],dp2[MAXN][MAXM],tmp[MAXM];
//dp1[u][k]表示的是\sum_{j在i的子树内(包括i)} \binom{dist(i,j)}{k}
//dp2[u][k]表示的是\sum_{j=1}^{n} \binom{dist(i,j)}{k} void dfs1 (int u,int fa){
dp1[u][0] = 1;
for (Int i = head[u];i;i = e[i].nxt){
int v = e[i].v;
if (v == fa) continue;
dfs1 (v,u);
for (Int j = 1;j <= k;++ j) dp1[u][j] = add (dp1[u][j],add (dp1[v][j],dp1[v][j - 1]));
dp1[u][0] = add (dp1[u][0],dp1[v][0]);
}
} void dfs2 (int u,int fa){//换根dp
for (Int i = 0;i <= k;++ i) dp2[u][i] = dp1[u][i];
if (fa){
for (Int i = 1;i <= k;++ i) tmp[i] = dec (dp2[fa][i],add (dp1[u][i],dp1[u][i - 1]));
tmp[0] = dec (dp2[fa][0],dp1[u][0]);
for (Int i = 1;i <= k;++ i) dp2[u][i] = add (dp2[u][i],add (tmp[i],tmp[i - 1]));
dp2[u][0] = add (dp2[u][0],tmp[0]);
}
for (Int i = head[u];i;i = e[i].nxt){
int v = e[i].v;
if (v == fa) continue;
dfs2 (v,u);
}
} template <typename T> inline void read (T &t){t = 0;char c = getchar();int f = 1;while (c < '0' || c > '9'){if (c == '-') f = -f;c = getchar();}while (c >= '0' && c <= '9'){t = (t << 3) + (t << 1) + c - '0';c = getchar();} t *= f;}
template <typename T,typename ... Args> inline void read (T &t,Args&... args){read (t);read (args...);}
template <typename T> inline void write (T x){if (x < 0){x = -x;putchar ('-');}if (x > 9) write (x / 10);putchar (x % 10 + '0');} signed main(){
read (n,k),S[0][0] = fac[0] = 1;
for (Int i = 1;i <= k;fac[i] = mul (i,fac[i - 1]),++ i)
for (Int j = 1;j <= i;++ j)
S[i][j] = add (S[i - 1][j - 1],mul (j,S[i - 1][j]));
for (Int i = 2,u,v;i <= n;++ i) read (u,v),Add_Edge (u,v);
dfs1 (1,0),dfs2 (1,0);
for (Int i = 1;i <= n;++ i){
int sum = 0;
for (Int j = 0;j <= k;++ j) sum = add (sum,mul (fac[j],mul (S[k][j],dp2[i][j])));
write (sum),putchar ('\n');
}
return 0;
}

题解 Crash 的文明世界的更多相关文章

  1. 【BZOJ2159】Crash的文明世界(第二类斯特林数,动态规划)

    [BZOJ2159]Crash的文明世界(第二类斯特林数,动态规划) 题面 BZOJ 洛谷 题解 看到\(k\)次方的式子就可以往二项式的展开上面考,但是显然这样子的复杂度会有一个\(O(k^2)\) ...

  2. P4827「国家集训队」 Crash 的文明世界

    「国家集训队」 Crash 的文明世界 提供一种不需要脑子的方法. 其实是看洛谷讨论版看出来的( (但是全网也就这一篇这个方法的题解了) 首先这是一个关于树上路径的问题,我们可以无脑上点分治. 考虑当 ...

  3. 【BZOJ2159】Crash的文明世界

    [2011集训贾志鹏]Crash的文明世界 Description Crash小朋友最近迷上了一款游戏--文明5(Civilization V).在这个游戏中,玩家可以建立和发展自己的国家,通过外交和 ...

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

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

  5. 题解 [BZOJ2159] Crash的文明世界

    题面 解析 这题一眼换根DP啊 首先,我们考虑一下如何转换\(n^m\)这个式子, 先把式子摆出来吧:\(n^m=\sum_{j=0}^mS(m,j)C_n^jj!\) 其中\(S(m,j)\)表示第 ...

  6. [题解] LuoguP4827 [国家集训队] Crash 的文明世界

    传送门 这个题......我谔谔 首先可以考虑换根\(dp\),但到后来发现二项式定理展开过后需要维护\(k\)个值,同时每个值也要\(O(k)\)的时间按二项式定理算 当然fft优化过后就是k lo ...

  7. 【bzoj 2159】Crash 的文明世界

    Description Crash小朋友最近迷上了一款游戏——文明5(Civilization V).在这个游戏中,玩家可以建立和发展自己的国家,通过外交和别的国家交流,或是通过战争征服别的国家.现在 ...

  8. bzoj 2159: Crash 的文明世界

    Time Limit: 10 Sec  Memory Limit: 259 MB Submit: 480  Solved: 234[Submit][Status][Discuss] Descripti ...

  9. 【BZOJ2159】Crash的文明世界 斯特林数+树形dp

    Description Crash 小朋友最近迷上了一款游戏--文明5(Civilization V).在这个游戏中,玩家可以建立和发展自己的国家,通过外交和别的国家交流,或是通过战争征服别的国家.现 ...

随机推荐

  1. python实现两台不同主机之间进行通信(客户端和服务端)——Socket

    大家好,我是辰哥~ 今天教大家通过Python进行Socket网络编程 (做一个聊天程序) 可以实现在不同的主机(电脑)之间进行通话. 具体效果如何,接着往下看 可以看到客户端(上方)向服务器端(下方 ...

  2. Nginx反向代理之巨坑underscores_in_headers

    一.背景 因为项目需求,在做Windows的相关的事情:基本架构就是Nginx--> Nginx --> IIS,在Linux机器上通过Nginx做反向代理到Windows的IIS:然后遇 ...

  3. Java基础之SPI机制

    SPI 机制,全称为 Service Provider Interface,是一种服务发现机制.它通过在 ClassPath 路径下的 META-INF/services 文件夹查找文件,自动加载文件 ...

  4. 多个mysql同时运行

    一.准备 mysql下载地址 https://dev.mysql.com/downloads/mysql/ 1.下载 2.解压缩 3.创建my.ini [Client] port = 3307 [my ...

  5. shell运算方式

    1.(())--整数运算 [root@m01 /server/scripts]# a=1 [root@m01 /server/scripts]# b=2 [root@m01 /server/scrip ...

  6. [考试总结]noip模拟46

    脑袋确实是不好使了需要回家暴颓治疗 数数数树鼠树 真好玩. 数数 大水题一个,妥妥的签到题目,然后... 我没签上 气展了!!! 其实我还是想麻烦了. 就是我们实际上就是排序之后每一次找头上和尾巴上的 ...

  7. Linux从头学12:读完这篇【特权级】文章,你就比别人更“精通”操作系统!

    作 者:道哥,10+年嵌入式开发老兵,专注于:C/C++.嵌入式.Linux. 关注下方公众号,回复[书籍],获取 Linux.嵌入式领域经典书籍:回复[PDF],获取所有原创文章( PDF 格式). ...

  8. 1.24学习总结——HTML常见标签

    HTML 标签简写及全称 下表列出了 HTML 标签简写及全称: 标签 英文全称 中文说明 a Anchor 锚 abbr Abbreviation 缩写词 acronym Acronym 取首字母的 ...

  9. Mysql backup and Recovery Data Type.

    数据库备份方法: 备份类型:物理备份和逻辑备份: 物理备份是指直接复制存储数据库内容的目录和文件,这种类型的备份适用于出现问题时需要快速恢复的大型重要数据库.逻辑备份保存以逻辑数据库结构(create ...

  10. html jquey的选择器checkbox,select

    1 判断checkbox是否选中 用到 jquery的 is方法 jquery: <div id="divId" class="divTable"> ...