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. B/S(WEB)系统中使用Activex插件调用扫描仪实现连续扫描并上传图像(IE文件扫描并自动上传)

    IE浏览器下使用Activex插件调用客户端扫描仪扫描文件并山传,可以将纸质档案(如合同.文件.资料等)扫描并将扫描图像保存到服务器,可以用于合同管理.档案管理等. 通过插件方式调用扫描仪扫描并获取图 ...

  2. hash_map与unordered_map区别

    http://blog.csdn.net/blues1021/article/details/45054159

  3. POJ3262 Protecting the Flowers 【贪心】

    Protecting the Flowers Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 4418   Accepted: ...

  4. HiWorkV1.3版震撼公布,今日起正式公开測试!

    今天HiWork迎来了公开測试和V1.3大版本号更迭,HiWork集成的机器人达到20种,未读消息提醒亦可从不同维度进行设置,不断变好真是件振奋人心的事儿呢. 在这个看重颜值(kan lian)的互联 ...

  5. Redhat Linux 下安装Oracle 11g R2

    能够下载:http://download.csdn.net/detail/ykh554541184/8086647文档方便查阅 官方文档:http://docs.oracle.com/cd/E1188 ...

  6. arcgis 发布地图服务

    arcgis中,地图文档需要发布,才能为WEB所用. 咋发布呢? 1.在arcmap里面,点击 文件 - 共享为 - 服务 2.在弹出的对话框里选"发布服务",然后 3.这里面有点 ...

  7. WEB服务器安装oracle jdbc

    WEB服务器,如果想采用jdbc访问另一台Oracle数据库服务器,那么它应该先安装Oracle客户端,或者要安装oracle jdbc. 那么怎样安装oracle jdbc呢? 1.到oracle下 ...

  8. PyTorch 60 分钟入门教程:PyTorch 深度学习官方入门中文教程

    什么是 PyTorch? PyTorch 是一个基于 Python 的科学计算包,主要定位两类人群: NumPy 的替代品,可以利用 GPU 的性能进行计算. 深度学习研究平台拥有足够的灵活性和速度 ...

  9. 请说出作用域public,private,protected,以及不写时的区别

    这四个作用域的可见范围如下表所示. 说明:如果在修饰的元素上面没有写任何访问修饰符,则表示friendly. 作用域    当前类 同一package 子孙类 其他package public    ...

  10. Linux的进程优先级NI和PR到底有什么区别

    Linux的进程优先级NI和PR到底有什么区别 - 51CTO.COM http://os.51cto.com/art/201605/511559.htm