BZOJ2159 Crash的文明世界
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}$$
\]
\]
\]
\]
\]
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的文明世界的更多相关文章
- BZOJ2159 Crash的文明世界(树形dp+斯特林数)
根据组合意义,有nk=ΣC(n,i)*i!*S(k,i) (i=0~k),即将k个有标号球放进n个有标号盒子的方案数=在n个盒子中选i个将k个有标号球放入并且每个盒子至少有一个球. 回到本题,可以令f ...
- BZOJ2159 Crash 的文明世界 【第二类斯特林数 + 树形dp】
题目链接 BZOJ2159 题解 显然不能直接做点分之类的,观察式子中存在式子\(n^k\) 可以考虑到 \[n^k = \sum\limits_{i = 0} \begin{Bmatrix} k \ ...
- 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)$. 则可以利 ...
- [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( ...
- BZOJ2159 Crash的文明世界——树上DP&&第二类Stirling数
题意 给定一个有 $n$ 个结点的树,设 $S(i)$ 为第 $i$ 个结点的“指标值”,定义为 $S(i)=\sum_{i=1}^{n}dist(i,j)^k$,$dist(i, j)$ 为结点 $ ...
- 题解 [BZOJ2159] Crash的文明世界
题面 解析 这题一眼换根DP啊 首先,我们考虑一下如何转换\(n^m\)这个式子, 先把式子摆出来吧:\(n^m=\sum_{j=0}^mS(m,j)C_n^jj!\) 其中\(S(m,j)\)表示第 ...
- 【BZOJ2159】Crash的文明世界(第二类斯特林数,动态规划)
[BZOJ2159]Crash的文明世界(第二类斯特林数,动态规划) 题面 BZOJ 洛谷 题解 看到\(k\)次方的式子就可以往二项式的展开上面考,但是显然这样子的复杂度会有一个\(O(k^2)\) ...
- 【BZOJ2159】Crash的文明世界
[2011集训贾志鹏]Crash的文明世界 Description Crash小朋友最近迷上了一款游戏--文明5(Civilization V).在这个游戏中,玩家可以建立和发展自己的国家,通过外交和 ...
- [国家集训队] Crash 的文明世界(第二类斯特林数)
题目 [国家集训队] Crash 的文明世界 前置 斯特林数\(\Longrightarrow\)斯特林数及反演总结 做法 \[\begin{aligned} ans_x&=\sum\limi ...
随机推荐
- 微服务 Framework
Dubbo :https://github.com/dubbo Spring Cloud :https://github.com/spring-cloud
- 【APUE】关于信号的一些常用函数
kill和raise函数 #include <signal.h> int kill(pid_t pid,int signo); int raise(int signo);//两个函数返回值 ...
- 分享:APK高级保护方法解析(三)
刷朋友圈.玩游戏.看新闻,智能手机正在以我们无法想象的速度飞快发展,可是随之而来的安全问题也越来越引人关注,APP二次打包.反编译.盗版的现象屡见不鲜.因此须要对APK进行加固保护. 眼下市面上常见的 ...
- ganglia监控自己定义metric实践
Ganglia监控系统是UC Berkeley开源的一个项目,设计初衷就是要做好分布式集群的监控.监控层面包含资源层面和业务层面,资源层面包含cpu.memory.disk.IO.网络负载等,至于业务 ...
- 《coredump问题原理探究》Linux x86版7.9节list相关的iterator对象
这一节.看一下list的iterator对象在内存的布局 1 #include <list> 2 3 void init( std::list<int>& lst ) ...
- Linux 简单的Shell输出
echo:用于输出指定字符串或用于在Shell中打印Shell变量的值 语法格式:echo [选项] [参数] -n:不输出换行 linlin@ubuntu:~/linlin/text$ ...
- 十分简洁的手机浏览器 lydiabox
没有地址栏,没有工具栏.web app无需下载.无需安装.无需更新,加入即用:再也不用记住网址.更不用输入网址--一款这样极简极方便的浏览器,你想要吗? 我们做了一个十分简洁的手机浏览器,这个浏览器也 ...
- jQuery操作Form表单元素
Web开发中常常须要操作表单,form表单元素有select.checkbox.radio.textarea.button.file.text.hidden.password等. 当中checkbox ...
- 【iOS9系列】-3DTouch开发
[iOS9系列]-3DTouch开发 第一:简介 3DTouch 是iOS9系统系统下,在iPhone6s(iPhone6s Plus)手机上才能够使用的功能.熟练使用后,发现还是很便捷的. 但是模拟 ...
- 基于Cocos2dx + box2d 实现的愤慨的小鸟Demo
1. Demo初始界面 2. 游戏界面 3. 精确碰撞检測 4. 下载 压缩文件文件夹 AngryBird source 愤慨的小鸟Demo源码,基于Cocos2dx C++,以及box2d技 ...