【BZOJ2159】Crash的文明世界 斯特林数+树形dp
Description
Crash 小朋友最近迷上了一款游戏——文明5(Civilization V)。在这个游戏中,玩家可以建立和发展自己的国家,通过外交和别的国家交流,或是通过战争征服别的国家。现在Crash 已经拥有了一个N 个城市的国家,这些城市之间通过道路相连。由于建设道路是有花费的,因此Crash 只修建了N-1 条道路连接这些城市,不过可以保证任意两个城市都有路径相通。在游戏中,Crash 需要选择一个城市作为他的国家的首都,选择首都需要考虑很多指标,有一个指标是这样的:
其中S(i)表示第i 个城市的指标值,dist(i, j)表示第i 个城市到第j 个城市需要经过的道路条数的最小值,k 为一个常数且为正整数。因此Crash 交给你一个简单的任务:给出城市之间的道路,对于每个城市,输出这个城市的指标值,由于指标值可能会很大,所以你只需要输出这个数mod 10007 的值。
Input
输入的第一行包括两个正整数N 和k。下面有N-1 行,每行两个正整数u、v (1 ≤ u, v ≤ N),表示第u 个城市和第v 个城市之间有道路相连。这些道路保证能符合题目的要求。
Output
输出共N 行,每行一个正整数,第i 行的正整数表示第i 个城市的指标值 mod 10007 的值。
Sample Input
5 2
1 2
1 3
2 4
2 5
Sample Output
10
7
23
18
18
HINT
20%的数据满足N ≤ 5000、k ≤ 30。 50%的数据满足N ≤ 50000、k ≤ 30。 100%的数据满足N ≤ 50000、k ≤ 150。 【特别注意】由于数据大小限制为5MB,我只好对测试时的输入文件进行压缩处理。下面的函数可以将压缩的输入文件转化为原始输入文件。(函数从infile 中读入压缩的输入文件,将解压缩后的输入文件输出到outfile 中) C/C++版本: void Uncompress(FILE *infile, FILE *outfile) { int N, k, L, i, now, A, B, Q, tmp; fscanf(infile, "%d%d%d", &N, &k, &L); fscanf(infile, "%d%d%d%d", &now, &A, &B, &Q); fprintf(outfile, "%d %d\n", N, k); for (i = 1; i < N; i ++) { now = (now * A + B) % Q; tmp = (i < L) ? i : L; fprintf(outfile, "%d %d\n", i - now % tmp, i + 1); } } Pascal 版本: procedure Uncompress(var infile, outfile : text); var N, k, L, i, now, A, B, Q, tmp : longint; begin read(infile, N, k, L, now, A, B, Q); writeln(outfile, N, ' ', k); for i := 1 to N - 1 do begin now := (now * A + B) mod Q; if i < L then tmp := i else tmp := L; writeln(outfile, i - now mod tmp, ' ', i + 1); end; end; 下面给出一个具体的例子。civiliazation_compressed.in 表示压缩的输入文件, civilization.in 表示解压缩后的输入文件。 civilization_compressed.in 7 26 4 29643 2347 5431 54209 civilization.in 7 26 1 2 2 3 2 4 3 5 4 6 5 7
Sol
\(x^n\)可以用第二类斯特林数和\(A^j_i\)来表示,\(A^j_i\)又可以用\(C_i^j*j!\)表示,而\(C(i,j)=C(i-1,j-1)+C(i-1,j)\),因为有这个式子,我们可以围绕组合数递推公式来进行\(dp\)。
设\(down[x][i]\)表示\(x\)的子树对\(x\)的贡献,\(up[x][i]\)表示除了\(x\)子树外的节点对\(x\)的贡献。设\(v\)为\(x\)的儿子,容易推出:
$down[x][k]=down[x][k]+down[v][k]+down[v][k-1] $
$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] $
\(up\)的最后两个递推式减去的分别是\(x\)的子树对\(up[fa,k]\)和\(up[fa,k-1]\)的贡献。
Code
#include <bits/stdc++.h>
using namespace std;
int S[205][205],F[205],U[100005][205],D[100005][205],n,m,L,now,tmp,x,y,A,B,Q,M=10007;vector<int>e[100005];
void dfs1(int x,int fa)
{
D[x][0]=1;for(int i=0;i<e[x].size();i++) if(e[x][i]!=fa)
{
dfs1(e[x][i],x);D[x][0]+=D[e[x][i]][0];
for(int j=1;j<=m;j++) D[x][j]=(D[x][j]+D[e[x][i]][j]+D[e[x][i]][j-1])%M;
}
}
void G(int x,int fa){for(int j=1;j<=m;j++) U[x][j]=(U[x][j]+U[fa][j]+U[fa][j-1]+D[fa][j]+D[fa][j-1]-D[x][j]-D[x][j-1]-D[x][j-1]-D[x][j-2]+10*M)%M;}
void dfs2(int x,int fa){if(fa) U[x][0]=n-D[x][0],G(x,fa);for(int i=0;i<e[x].size();i++) if(e[x][i]!=fa) dfs2(e[x][i],x);}
int main()
{
scanf("%d%d%d%d%d%d%d",&n,&m,&L,&now,&A,&B,&Q);
for(int i=1;i<n;i++) now=(now*A+B)%Q,tmp=i<L?i:L,x=i-now%tmp,y=i+1,e[x].push_back(y),e[y].push_back(x);
S[0][0]=F[0]=1;for(int i=1;i<=m;F[i]=F[i-1]*i%M,i++) for(int j=1;j<=i;j++) S[i][j]=(S[i-1][j]*j%M+S[i-1][j-1])%M;
dfs1(1,0);dfs2(1,0);
for(int i=1,A=0;i<=n;printf("%d\n",A),i++,A=0) for(int j=1;j<=m;j++) A=(A+1ll*S[m][j]*F[j]%M*(U[i][j]+D[i][j])%M)%M;
}
【BZOJ2159】Crash的文明世界 斯特林数+树形dp的更多相关文章
- [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( ...
- BZOJ.2159.Crash的文明世界(斯特林数 树形DP)
BZOJ 洛谷 挺套路但并不难的一道题 \(Description\) 给定一棵\(n\)个点的树和\(K\),边权为\(1\).对于每个点\(x\),求\(S(x)=\sum_{i=1}^ndis( ...
- 洛谷P4827 [国家集训队] Crash 的文明世界 [斯特林数,组合数,DP]
传送门 思路 又见到这个\(k\)次方啦!按照套路,我们将它搞成斯特林数: \[ ans_x=\sum_{i=0}^k i!S(k,i)\sum_y {dis(x,y) \choose i} \] 前 ...
- Luogu4827 Crash的文明世界 组合、树形DP
传送门 又是喜闻乐见的\(k\)次幂求和题目 那么\(S(x) = \sum\limits_{i=1}^n dist(i,x)^k = \sum\limits_{i=1}^n \sum\limits_ ...
- bzoj 2159 Crash 的文明世界 && hdu 4625 JZPTREE ——第二类斯特林数+树形DP
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2159 学习材料:https://blog.csdn.net/litble/article/d ...
- P4827 [国家集训队] Crash 的文明世界(第二类斯特林数+树形dp)
传送门 对于点\(u\),所求为\[\sum_{i=1}^ndis(i,u)^k\] 把后面那堆东西化成第二类斯特林数,有\[\sum_{i=1}^n\sum_{j=0}^kS(k,j)\times ...
- bzoj 2159 Crash 的文明世界 & hdu 4625 JZPTREE —— 第二类斯特林数+树形DP
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2159 使用公式:\( n^{k} = \sum\limits_{i=0}^{k} S(k,i ...
- BZOJ 2159: Crash 的文明世界(组合数学+第二类斯特林数+树形dp)
传送门 解题思路 比较有意思的一道数学题.首先\(n*k^2\)的做法比较好想,就是维护一个\(x^i\)这种东西,然后转移的时候用二项式定理拆开转移.然后有一个比较有意思的结论就是把求\(x^i\) ...
- BZOJ2159 Crash的文明世界——树上DP&&第二类Stirling数
题意 给定一个有 $n$ 个结点的树,设 $S(i)$ 为第 $i$ 个结点的“指标值”,定义为 $S(i)=\sum_{i=1}^{n}dist(i,j)^k$,$dist(i, j)$ 为结点 $ ...
随机推荐
- mul 指令
mul 是乘法指令 两个相乘的数:两个相乘的数,要么都是 8 位,要么都是 16 位. 如果是 8 位,一个默认放在 AL 中,另一个放在 8 位寄存器或内存字节单元中: 如果是 16 位,一个默认在 ...
- pthread thread mutex synchronous asynchronous communication
设置进程绑定状态的函数pthread_attr_setscopepthread_attr_t 指向属性结构的指针第二个参数 绑定类型 pthread_scope_system()pthread_sco ...
- HTTP直接请求webService
在实际开发中,会遇到各种各样的webService接口,并且对方提供的接口并不规范,一些客户端反而就不好使了,如cxf(客户端与动态调用)等,直接用java提供的api比较繁琐,这时直接用http r ...
- https ssl
HTTPS(全称:Hyper Text Transfer Protocol over Secure Socket Layer),是以安全为目标的HTTP通道,简单讲是HTTP的安全版.即HTTP下加入 ...
- 仿函数(二、stl中常用仿函数)
提到C++ STL,首先被人想到的是它的三大组件:Containers, Iterators, Algorithms,即容器,迭代器和算法.容器为用户提供了常用的数据结构,算法大多是独立于容器的常用的 ...
- EKF model&realization
REF: https://pythonrobotics.readthedocs.io/en/latest/modules/localization.html#unscented-kalman-filt ...
- jsoup 的简单应用
导入相关jar包 package jsoup.zr.com.utils; import java.io.IOException; import java.util.List; import org.j ...
- c语言学习笔记 if语句的条件判断
可能经常会看到错误的if语句示范,比如这样的: if(a=6) { printf("hello"); } if语句块执行的条件是if条件的运算结果不是0则执行if语句块. a=6这 ...
- Java方法学习疑问
此方法不理解 finalize() 方法 Java允许定义这样的方法,它在对象被垃圾收集器析构(回收)之前调用,这个方法叫做finalize( ),它用来清除回收对象. 例如,你可以使用finaliz ...
- 2、python的print函数格式化输出
1.格式化输出浮点数(float) pi = 3.141592653 print('%10.3f' % pi) #字段宽10,精度3 ,结果 print('%010.3f' % pi) #用0填充 ...