Description

传送门

给你一个n个点的树,边权为1. 对于每个点u, 求:\(\sum_{i = 1}^{n} distance(u, i)^{k}\)

$ n \leq 50000, k \leq 150 $

Solution

咱们化一下式子:

\(\sum_{i = 1}^{n} distance(u,i) ^ {k}\)

\(=\sum_{i = 1}^{n} \sum_{j = 0}^{k} C(dis(u, i), j)* S2(k, j) * j!\)

\(=\sum_{j = 0}^{k} S2(k,j) * j! * \sum_{i = 1}^{n} C(dis(u, i), j)\)

令\(dp[u][j] = \sum_{i = 1}^{n} C(dis(u, i), j)\)

那么设$down[u][j] $ 表示\(i \in subtree[u]\)的解, \(up[u][j]\)表示$ i \in tree - subtree[u]$的解

那么显然, 根据组合数性质:$${n \choose k} = {n - 1 \choose k} + {n - 1 \choose k - 1}$$

\[down[u][j] = down[son][j - 1] + down[son][j]
\]

\[up[x][k]=up[x][k]+up[fa][k]+up[fa][k-1]
\]

\[up[x][k]=up[x][k]+down[fa][k]+down[fa][k-1]
\]

\[up[x][k]=up[x][k]-down[x][k]-down[x][k-1]
\]

\[up[x][k]=up[x][k]-down[x][k-1]-down[x][k-2]
\]

Codes

#include<bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for(int i = (a), i##_end_ = (b); i <= i##_end_; ++i)
#define drep(i, a, b) for(int i = (a), i##_end_ = (b); i >= i##_end_; --i)
#define clar(a, b) memset((a), (b), sizeof(a))
#define debug(...) fprintf(stderr, __VA_ARGS__)
#define Debug(s) debug("The massage in line %d, Function %s: %s\n", __LINE__, __FUNCTION__, s)
typedef long long LL;
typedef long double LD;
const int BUF_SIZE = (int)1e6 + 10;
struct fastIO {
char buf[BUF_SIZE], buf1[BUF_SIZE];
int cur, cur1;
FILE *in, *out;
fastIO() {
cur = BUF_SIZE, in = stdin, out = stdout;
cur1 = 0;
}
inline char getchar() {
if(cur == BUF_SIZE) fread(buf, BUF_SIZE, 1, in), cur = 0;
return *(buf + (cur++));
}
inline void putchar(char ch) {
*(buf1 + (cur1++)) = ch;
if (cur1 == BUF_SIZE) fwrite(buf1, BUF_SIZE, 1, out), cur1 = 0;
}
inline int flush() {
if (cur1 > 0) fwrite(buf1, cur1, 1, out);
return cur1 = 0;
}
}IO;
#define getchar IO.getchar
#define putchar IO.putchar
int read() {
char ch = getchar();
int x = 0, flag = 1;
for(;!isdigit(ch); ch = getchar()) if(ch == '-') flag *= -1;
for(;isdigit(ch); ch = getchar()) x = x * 10 + ch - 48;
return x * flag;
}
void write(int x) {
if(x < 0) putchar('-'), x = -x;
if(x >= 10) write(x / 10);
putchar(x % 10 + 48);
}
void putString(char s[], char EndChar = '\n') {
rep(i, 0, strlen(s) - 1) putchar(*(s + i));
if(~EndChar) putchar(EndChar);
} #define Mod 10007
#define Maxn 50009
#define Maxk 159
struct edge {
int to, nxt;
}g[Maxn << 1];
int n, k, head[Maxn], e, fac[Maxn], up[Maxn][Maxk], down[Maxn][Maxk], s[Maxk][Maxk];
namespace INIT {
void add(int u, int v) {
g[++e] = {v, head[u]}, head[u] = e;
}
void Main() {
clar(head, -1);
n = read(), k = read();
rep(i, 1, n - 1) {
int u = read(), v = read();
add(v, u), add(u, v);
}
s[0][0] = 1;
rep(i, 1, k)
rep(j, 1, i) s[i][j] = (s[i - 1][j - 1] + j * s[i - 1][j]) % Mod;
fac[0] = 1;
rep(i, 1, k) fac[i] = fac[i - 1] * i % Mod;
}
}
namespace SOLVE {
int S[Maxn];
void dfs(int u, int fa) {
down[u][0] = 1;
for(int i = head[u]; ~i; i = g[i].nxt) {
int v = g[i].to;
if(v != fa) {
dfs(v, u);
(down[u][0] += down[v][0]) %= Mod;
rep(j, 1, k) (down[u][j] += (down[v][j] + down[v][j - 1]) % Mod) %= Mod;
}
}
}
void dfs1(int u, int fa) {
for(int i = head[u]; ~i; i = g[i].nxt) {
int v = g[i].to;
if(v != fa) {
up[v][0] = (n - down[v][0]) % Mod;
rep(j, 1, k) {
(up[v][j] += up[u][j - 1] + up[u][j]) %= Mod;
(up[v][j] += down[u][j - 1] + down[u][j]) %= Mod;
(up[v][j] -= (down[v][j - 1] + down[v][j - 2]) % Mod - Mod) %= Mod;
(up[v][j] -= (down[v][j - 1] + down[v][j]) % Mod - Mod) %= Mod;
}
dfs1(v, u);
}
}
}
void Main() {
dfs(1, 0), dfs1(1, 0);
rep(i, 1, k) {
int Tmp = fac[i] * s[k][i] % Mod;
rep(j, 1, n) S[j] += (Tmp * (up[j][i] + down[j][i])) % Mod;
}
rep(i, 1, n) printf("%d\n", S[i] % Mod);
}
}
int main() {
#ifdef Qrsikno
freopen("BZOJ2159.in", "r", stdin);
freopen("BZOJ2159.out", "w", stdout);
#endif
INIT :: Main();
SOLVE :: Main();
#ifdef Qrsikno
debug("\nRunning time: %.3lf(s)\n", clock() * 1.0 / CLOCKS_PER_SEC);
#endif
return IO.flush();
}

BZOJ2159 Crash的文明世界的更多相关文章

  1. BZOJ2159 Crash的文明世界(树形dp+斯特林数)

    根据组合意义,有nk=ΣC(n,i)*i!*S(k,i) (i=0~k),即将k个有标号球放进n个有标号盒子的方案数=在n个盒子中选i个将k个有标号球放入并且每个盒子至少有一个球. 回到本题,可以令f ...

  2. BZOJ2159 Crash 的文明世界 【第二类斯特林数 + 树形dp】

    题目链接 BZOJ2159 题解 显然不能直接做点分之类的,观察式子中存在式子\(n^k\) 可以考虑到 \[n^k = \sum\limits_{i = 0} \begin{Bmatrix} k \ ...

  3. BZOJ2159 : Crash 的文明世界

    $x^k=\sum_{i=1}^k Stirling2(k,i)\times i!\times C(x,i)$ 设$f[i][j]=\sum_{k=1}^n C(dist(i,k),j)$. 则可以利 ...

  4. [BZOJ2159]Crash的文明世界(斯特林数+树形DP)

    题意:给定一棵树,求$S(i)=\sum_{j=1}^{n}dist(i,j)^k$.题解:根据斯特林数反演得到:$n^m=\sum_{i=0}^{n}C(n,i)\times i!\times S( ...

  5. BZOJ2159 Crash的文明世界——树上DP&&第二类Stirling数

    题意 给定一个有 $n$ 个结点的树,设 $S(i)$ 为第 $i$ 个结点的“指标值”,定义为 $S(i)=\sum_{i=1}^{n}dist(i,j)^k$,$dist(i, j)$ 为结点 $ ...

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

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

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

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

  8. 【BZOJ2159】Crash的文明世界

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

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

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

随机推荐

  1. Java读取文件时中文路径处理

    读取文件路径时可能存在以下情况: 1.空格,如果出现空格会转变成“%20” 2.中文路径,如果出现中文路径会变成URI编码“%e5%bc%80%e5%8f%91%e5%b7%a5%e7%a8%8b” ...

  2. Linux驱动开发:USB驱动之usb_skel分析

    在学习了这么些天的驱动之后,个人觉得驱动就是个架构的问题,只要把架构弄清楚了 然后往里面添砖加瓦就可以了,所以似乎看起来不是太困难,但也许是是我经验不足吧,这只能算是个人浅见了 这两天在学习USB驱动 ...

  3. iOS + Nodejs SSL/Https双向认证

    移动互联网的大力发展,安全越来越重要. 什么是双向认证呢?双向认证就是client要验证server的合法性,同一时候server也要验证client的合法性. 这样两方都相互验证,提高安全性. 关于 ...

  4. Servlet第七课:ServletContext HttpSession 以及HttpServletRequest之间的关系

    课程目标: ① 在Servlet中懂得ServletContext HttpSession 以及HttpServletRequest之间的关系 ② 懂得怎样使用它们 概念介绍: 1. [共同点]不管对 ...

  5. DBscan算法及其Python实现

    DBSCAN简介: 1.简介 DBSCAN 算法是一种基于密度的空间聚类算法.该算法利用基于密度的聚类的概念,即要求聚类空间中的一定区域内所包含对象(点或其它空间对象)的数目不小于某一给定阀值.DBS ...

  6. 关于mybatis的 insert into select 命令未结束问题

    关于mybatis的 insert into select 命令未结束问题,最后以为是sql写错了,可是,在plsql运行又没问题.最后还是解决这个问题. 是设置问题. ### Cause: java ...

  7. Hackrank Equal DP

    Christy is interning at HackerRank. One day she has to distribute some chocolates to her colleagues. ...

  8. 一场由过滤器Filter引发的血案

    一场由过滤器Filter引发的血案 事件起因 本来应该是下图的登录界面 变成了这样 What's the fuck????? 抓狂 原因 解决方法: 在过滤器中给资源文件开个绿色通道

  9. bash: crontab: command not found

    操作步骤 1. 确认crontab是否安装: 执行 crontab 命令如果报 command not found,就表明没有安装 2. 安装 crontab 执行 yum install -y vi ...

  10. C语言-1.static 和 extern使用,2.文件,3.数据块读写

    1.static 和 extern使用, 1)修饰局部变量 static修饰局部变量特点:延长局部变量的生命周期 ,static修饰的局部变量只会被执行一次 extern不能修饰局部变量 2)修饰全局 ...