【bzoj 2159】Crash 的文明世界

Description

Crash小朋友最近迷上了一款游戏——文明5(Civilization V)。在这个游戏中,玩家可以建立和发展自己的国家,通过外交和别的国家交流,或是通过战争征服别的国家。现在Crash已经拥有了一个N个城市的国家,这些城市之间通过道路相连。由于建设道路是有花费的,因此Crash只修建了N-1条道路连接这些城市,不过可以保证任意两个城市都有路径相通。在游戏中,Crash需要选择一个城市作为他的国家的首都,选择首都需要考虑很多指标,有一个指标是这样的:$S(i)=\sum _{j=1}^Ndist(i,j)^k$。其中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 的值。

用结论来化简式子:$x^n=\sum _{i=1}^n S(n,i)\cdot F(x,i)$

$S(n,i)$为第二类斯特林数,$F(x,i)=\frac{x!}{(x-i)!}$

可得:$$\begin{align*} ans(i)&=\sum _{j=1}^ndist(i,j)^m\\ &=\sum_{j=1}^{n}\sum_{k=1}^{m}S(m,k)\cdot F(dist(i,j),k)\\ &=\sum_{k=1}^{m}S(m,k)\sum_{j=1}^{n} F(dist(i,j),k)\\ &=\sum_{k=1}^{m}S(m,k)\cdot k!\cdot \sum_{j=1}^{n} C(dist(i,j),k) \end{align*}$$

根据组合数递推公式:$C(n,m)=C(n-1,m)+C(n-1,m-1)$ 就可以很方便的对后面的部分进行树形dp了。

具体地,令 $up(x,i)$ 为不在 $x$ 的子树中的部分的贡献,令 $dn(x,i)$ 为 $x$ 的子树的贡献。特别的,$dn(x,0)=1$。

详见代码。

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 #define LL long long
 5 using namespace std;
 6 const int N=5e4+5;
 7 const int M=155;
 8 const int mod=1e4+7;
 9 int n,m,u,v,cnt,ans,tmp;
10 int first[N],fac[M],s[M][M];
11 int up[N][M],dn[N][M];
12 struct edge{int to,next;}e[N*2];
13 int read()
14 {
15     int x=0,f=1;char c=getchar();
16     while(c<‘0‘||c>‘9‘){if(c==‘-‘)f=-1;c=getchar();}
17     while(c>=‘0‘&&c<=‘9‘){x=x*10+c-‘0‘;c=getchar();}
18     return x*f;
19 }
20 void ins(int u,int v){e[++cnt]=(edge){v,first[u]};first[u]=cnt;}
21 void Mod(int& a,int b){a+=b;if(a>=mod)a-=mod;}
22 void dfs1(int x,int fa)
23 {
24     dn[x][0]=1;
25     for(int i=first[x];i;i=e[i].next)
26     {
27         int to=e[i].to;
28         if(to==fa)continue;
29         dfs1(to,x);
30         Mod(dn[x][0],dn[to][0]);
31         for(int j=1;j<=m;j++)
32             Mod(dn[x][j],(dn[to][j]+dn[to][j-1])%mod);
33     }
34 }
35 void dfs2(int x,int fa)
36 {
37     if(fa!=-1)
38     {
39         up[x][0]=n-dn[x][0];
40         for(int i=1;i<=m;i++)
41         {
42             Mod(up[x][i],(up[fa][i]+up[fa][i-1])%mod);
43             Mod(up[x][i],(dn[fa][i]+dn[fa][i-1])%mod);
44             Mod(up[x][i],(2*mod-dn[x][i]-dn[x][i-1])%mod);
45             Mod(up[x][i],(mod-dn[x][i-1])%mod);
46             if(i!=1)Mod(up[x][i],(mod-dn[x][i-2])%mod);
47         }
48     }
49     for(int i=first[x];i;i=e[i].next)
50         if(e[i].to!=fa)dfs2(e[i].to,x);
51 }
52 int main()
53 {
54     int L,now,A,B,Q;
55     n=read();m=read();L=read();
56     now=read();A=read();B=read();Q=read();
57     for(int i=1;i<n;i++)
58     {
59         now=(now*A+B)%Q;
60         tmp=i<L?i:L;
61         u=i-now%tmp;v=i+1;
62         ins(u,v);ins(v,u);
63     }
64 //    n=read();m=read();
65 //    for(int i=1;i<n;i++)
66 //    {
67 //        u=read();v=read();
68 //        ins(u,v);ins(v,u);
69 //    }
70     fac[0]=s[0][0]=1;
71     for(int i=1;i<=m;i++)
72     {
73         fac[i]=fac[i-1]*i%mod;
74         for(int j=1;j<=i;j++)
75             s[i][j]=(s[i-1][j]*j+s[i-1][j-1])%mod;
76     }
77     dfs1(1,-1);dfs2(1,-1);
78     for(int i=1;i<=n;i++)
79     {
80         ans=0;
81         for(int j=1;j<=m;j++)
82             Mod(ans,s[m][j]*fac[j]%mod*(up[i][j]+dn[i][j])%mod);
83         printf("%d\n",ans);
84     }
85     return 0;
86 }

原文地址:https://www.cnblogs.com/zsnuo/p/8926030.html

时间: 2024-11-09 10:12:46

【bzoj 2159】Crash 的文明世界的相关文章

bzoj 2159: Crash 的文明世界

2159: Crash 的文明世界 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 478  Solved: 233[Submit][Status][Discuss] Description Crash 小朋友最近迷上了一款游戏——文明5(Civilization V).在这个游戏中,玩家可以建立和发展自己的国家,通过外交和别的国家交流,或是通过战争征服别的国家.现在Crash 已经拥有了一个N 个城市的国家,这些城市之间通过道路相连.由于建设道路

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

题意: 给定一棵 \(n\) 个点的树和一个常数 \(k\) , 对于每个 \(i\) , 求 \[\displaystyle S(i) = \sum _{j=1} ^ {n} \mathrm{dist}(i, j)^k\] \(n ≤ 50000, k ≤ 150\) 题解 : 先划划那个 \(S(i)\) 的式子 我们需要知道一个化 \(x^n(n \ge 0)\) 的东西qwq \[\displaystyle x^n=\sum_{k=0}^{n}\begin{Bmatrix} n \\ k

bzoj 2159 Crash 的文明世界 —— 第二类斯特林数+树形DP

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2159 使用公式:\( n^{k} = \sum\limits_{i=0}^{k} S(k,i) * i! * C_{n}^{i} \) 所以维护 \( f[x][i] = \sum\limits_{u\in subtree[x],d=dist(x,u)}^{n} C_{d}^{i} \) 然后利用 \( C_{n}^{m} = C_{n-1}^{m} + C_{n-1}^{m-1} \),

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)$. 则可以利用$C(i,j)=C(i-1,j-1)+C(i-1,j)$,通过树形DP求出$f$. 时间复杂度$O((n+k)k)$. #include<cstdio> const int N=50010,M=155,P=10007; int n,k,i,j,x,y,S[M][M],fac[M],g[N],v[

【[国家集训队] Crash 的文明世界】

先写一个五十分的思路吧 首先这道题有一个弱化版 [POI2008]STA-Station 相当于\(k=1\),于是就是一个非常简单的树形\(dp\)的\(up\ \ and\ \ down\)思想 但是我们现在要求的是这个柿子了 \[\sum_{j=1}^ndis(i,j)^k\] 感觉这个东西很组合数学啊,感觉这个柿子像是天生为二项式定理准备的 我们还是考虑树形\(dp\) 在第一遍\(up\)的时候,我们设\(dp[i][k]\)表示 \[\sum_{j\in{i}}dis(i,j)^k\

P4827 [国家集训队] Crash 的文明世界(第二类斯特林数+树形dp)

传送门 对于点\(u\),所求为\[\sum_{i=1}^ndis(i,u)^k\] 把后面那堆东西化成第二类斯特林数,有\[\sum_{i=1}^n\sum_{j=0}^kS(k,j)\times j!\times{dis(i,u)\choose j}\] \[\sum_{j=1}^nS(k,j)\times j!\sum_{i=0}^k{dis(i,u)\choose j}\] 于是对于每个点只要维护好\(\sum_{i=0}^k{dis(i,u)\choose j}\)就好了 因为\({n

Luogu4827 Crash的文明世界 组合、树形DP

传送门 又是喜闻乐见的\(k\)次幂求和题目 那么\(S(x) = \sum\limits_{i=1}^n dist(i,x)^k = \sum\limits_{i=1}^n \sum\limits_{j=1}^k \binom{dist(i,x)}{j} \left\{ \begin{array}{cccc} k \\ j \end{array}\right\} j! = \sum\limits_{j=1}^k \left\{ \begin{array}{cccc} k \\ j \end{a

【莫比乌斯反演】关于Mobius反演与lcm的一些关系与问题简化(BZOJ 2154 crash的数字表格&amp;&amp;BZOJ 2693 jzptab)

BZOJ 2154 crash的数字表格 Description 今天的数学课上,Crash小朋友学习了最小公倍数(Least Common Multiple).对于两个正整数a和b,LCM(a, b)表示能同时被a和b整除的最小正整数.例如,LCM(6, 8) = 24.回到家后,Crash还在想着课上学的东西,为了研究最小公倍数,他画了一张N*M的表格.每个格子里写了一个数字,其中第i行第j列的那个格子里写着数为LCM(i, j).一个4*5的表格如下: 1 2 3 4 5 2 2 6 4

[bzoj 2154]Crash的数字表格

Description 今天的数学课上,Crash小朋友学习了最小公倍数(Least Common Multiple).对于两个正整数a和b,LCM(a, b)表示能同时被a和b整除的最小正整数.例如,LCM(6, 8) = 24.回到家后,Crash还在想着课上学的东西,为了研究最小公倍数,他画了一张N*M的表格.每个格子里写了一个数字,其中第i行第j列的那个格子里写着数为LCM(i, j).一个4*5的表格如下: 1 2 3 4 5 2 2 6 4 10 3 6 3 12 15 4 4 12