Time Limit: 10 Sec  Memory Limit: 259 MB

Submit: 480  Solved: 234
[Submit][Status][Discuss]

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

2016.2.19重设时限为10s

为什么要把输入改成这鬼样,,,,害得我一开始没看见RE。。。。

咳咳现在讲一下正解。
首先S(i)=Σdist(i,j)^k,这个看起来贼迷,但是我们有一个公式:
x^k=Σ(i=1 to k)  S(k,i)*P(x,i),  其中S是第二类斯特林数,P是排列数。

这样的话我们把这个套进S(i)里,就是:
S(i)=Σ(h=1 to k)S(k,h)*ΣP(dist(j,i),h),  又因为P(i,j)=C(i,j)*j!,所以变成C之后上式就是:
S(i)=Σ(h=1 to k)S(k,h)*h!*ΣC(dist(j,i),h)   。。。
貌似又陷入僵局了 ???
并不,后面的那个Σ是可以递推出来的,因为C(x,y)=C(x-1,y-1)+C(x-1,y).
所以我们设now[x][i]=ΣC(dist(x,v),i),其中v是以x为根的子树中的一点;
up[x][i]=ΣC(dist(x,v),i),其中v是以x为根的子树外的一点。

显然now[x][0]=1+Σnow[v][0], 因为任意C(g,0)都为1。
up[x][0]=n-now[x][0],因为显然子树内的点数+子树外的点数=n。

然后可以发现的是now[x][i]=Σ(now[v][i]+now[v][i-1]),其中v在以x为根的子树中。
这个不难理解,根据now的定义就可以推出。

主要是推up有一点小麻烦。
我们分类的话(设fa为x在树上的父亲),不在x为根的子树中的点无非分为两种:
    1.不在以fa为根的子树中的节点。
    2.在以fa为根的子树的不在以x为根的子树中的节点。

1的贡献就是up[fa][i-1]+up[fa][i],2的贡献就是{ now[fa][i]-(now[x][i]+now[x][i-1]) }+{ now[fa][i-1]-(now[x][i-1]+now[x][i-2]) }。

所以两次dfs就可以解决,最后把前面Σ后面的系数乘上加进答案就ojbk了。

code:

 #include<bits/stdc++.h>
#define maxn 50005
#define ll long long
#define ha 10007
#define pb push_back
using namespace std;
vector<int> g[maxn];
int now[maxn][],n,up[maxn][],k;
int uu,vv,ans,S[][],jc[]; inline void init(){
jc[]=;
for(int i=;i<=;i++) jc[i]=jc[i-]*i%ha;
S[][]=;
for(int i=;i<=;i++){
// S[i][0]=1;
for(int j=;j<=i;j++) S[i][j]=(S[i-][j-]+S[i-][j]*j)%ha;
}
} void dfs1(int x,int fa){
int to;
now[x][]=;
for(int i=g[x].size()-;i>=;i--){
to=g[x][i];
if(to==fa) continue;
dfs1(to,x);
now[x][]+=now[to][];
for(int j=;j<=k;j++){
now[x][j]+=now[to][j]+now[to][j-];
while(now[x][j]>=ha) now[x][j]-=ha;
}
up[x][]=n-now[x][];
}
} void dfs2(int x,int fa){
int to;
if(fa){
for(int i=;i<=k;i++){
up[x][i]=(up[fa][i]+up[fa][i-]+now[fa][i]+now[fa][i-]-now[x][i-]*-now[x][i]);
if(i>) up[x][i]-=now[x][i-];
up[x][i]=up[x][i]%ha+ha;
if(up[x][i]>=ha) up[x][i]-=ha;
}
} for(int i=g[x].size()-;i>=;i--){
to=g[x][i];
if(to==fa) continue;
dfs2(to,x);
}
} int main(){
init();
int L,NOW,A,B,Q;
scanf("%d%d%d%d%d%d%d",&n,&k,&L,&NOW,&A,&B,&Q);
for(int i=;i<n;i++){
NOW=(NOW*A+B)%Q;
int tmp=i<L?i:L;
uu=i-NOW%tmp,vv=i+;
g[uu].pb(vv),g[vv].pb(uu);
} dfs1(,);
dfs2(,); for(int i=;i<=n;i++){
ans=;
for(int j=;j<=k;j++) ans=(ans+S[k][j]*jc[j]%ha*(now[i][j]+up[i][j]))%ha;
printf("%d\n",ans);
}
return ;
}

bzoj 2159: Crash 的文明世界的更多相关文章

  1. BZOJ.2159.Crash的文明世界(斯特林数 树形DP)

    BZOJ 洛谷 挺套路但并不难的一道题 \(Description\) 给定一棵\(n\)个点的树和\(K\),边权为\(1\).对于每个点\(x\),求\(S(x)=\sum_{i=1}^ndis( ...

  2. BZOJ 2159: Crash 的文明世界(树形dp+第二类斯特林数+组合数)

    题意 给定一棵 \(n\) 个点的树和一个常数 \(k\) , 对于每个 \(i\) , 求 \[\displaystyle S(i) = \sum _{j=1} ^ {n} \mathrm{dist ...

  3. bzoj 2159 Crash 的文明世界 && hdu 4625 JZPTREE ——第二类斯特林数+树形DP

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2159 学习材料:https://blog.csdn.net/litble/article/d ...

  4. 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 ...

  5. [bzoj 2159]Crash的文明世界

    今天看到一个鬼题 心情好的时候写 [题意]求树上所有点对距离的k次方和,所有边权为1 大爷方的题解:http://tonyfang.is-programmer.com/posts/204972.htm ...

  6. bzoj 2159 - Crash 的 文明世界

    Description 给定一棵\(n\le 10^5\)的树, 和\(k\le 150\) 求每个点\(x\)的\[S(x) = \sum_{y=1}^n dis(x, y) ^ k\] Analy ...

  7. BZOJ 2159: Crash 的文明世界 第二类斯特林数+树形dp

    这个题非常巧妙啊~ #include <bits/stdc++.h> #define M 170 #define N 50003 #define mod 10007 #define LL ...

  8. BZOJ 2159: Crash 的文明世界(组合数学+第二类斯特林数+树形dp)

    传送门 解题思路 比较有意思的一道数学题.首先\(n*k^2\)的做法比较好想,就是维护一个\(x^i\)这种东西,然后转移的时候用二项式定理拆开转移.然后有一个比较有意思的结论就是把求\(x^i\) ...

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

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

随机推荐

  1. 2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛 H. Skiing (拓扑排序+假dp)

    题目链接:https://nanti.jisuanke.com/t/16957 题目: In this winter holiday, Bob has a plan for skiing at the ...

  2. @EnableEurekaClient源码分析

    @EnableEurekaClient注解,从源码的角度分析是如何work的 NetFlix Eureka client Eureka client 负责与Eureka Server 配合向外提供注册 ...

  3. Codeforces Round #483 (Div. 1) 简要题解

    来自FallDream的博客,未经允许,请勿转载,谢谢. 为了证明一下我又来更新了,写一篇简要的题解吧. 这场比赛好像有点神奇,E题莫名是道原题,导致有很多选手直接过掉了(Claris 表演24s过题 ...

  4. Java的9种基本数据类型的大小,以及他们的封装类

    由于java程序是运行在虚拟机之上的,所以java的基本数据类型的大小是确定的,不会随着操作系统的位数的改变而改变. 在计算机中,存储的是0,1,0,1这样的二进制位,表示为bit,1Byte = 8 ...

  5. monkey测试===Monkey测试结果分析(系列三)转

    Monkey测试结果分析 一. 初步分析方法: Monkey测试出现错误后,一般的差错步骤为以下几步: 1. 找到是monkey里面的哪个地方出错 2. 查看Monkey里面出错前的一些事件动作,并手 ...

  6. tenda t402 家庭版 有线路由器

    使用快速向导: adsl(拨号)+用户名+密码 路由器后DMZ主机设置简单图解:http://wenku.baidu.com/view/94b9f0768e9951e79b8927ce.html  可 ...

  7. Mongo 配置文件 [www]

    Mongo 配置文件  [www] http://blog.chinaunix.net/uid-25206403-id-3510934.html mongodb 安装使用 http://blog.si ...

  8. 设计模式之笔记--抽象工厂模式(Abstract Factory)

    抽象工厂模式(Abstract Factory) 定义 抽象工厂模式(Abstract Factory),提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类. 类图 描述 多个抽象产品 ...

  9. ConcurrentMap.putIfAbsent(key,value) 用法讨论

    ConcurrentMap.putIfAbsent(key,value) 用法讨论 http://wxl24life.iteye.com/blog/1746794

  10. 转载---HttpUrlConnection发送post请求汉字出现乱码的一个解决方法及其原因

    原文:http://blog.csdn.net/qqaazz211/article/details/52136187 在网上看到了这篇比较简单的解决方法,果然有用,特记之 解决方法是:将 out.wr ...