Crash小朋友最近迷上了一款遊戲——文明5(Civilization V)。在這個遊戲中,玩家能夠創建和發展本身的國家,經過外交和別的國家交流,或是經過戰爭征服別的國家。
如今Crash已經擁有了一個N個城市的國家,這些城市之間經過道路相連。因爲建設道路是有花費的,所以Crash只修建了N-1條道路鏈接這些城市,不過能夠保證任意兩個城市都有路徑相通。
在遊戲中,Crash須要選擇一個城市做爲他的國家的首都,選擇首都須要考慮不少指標,有一個指標是這樣的:
其中S(i)表示第i個城市的指標值,dist(i, j)表示第i個城市到第j個城市須要通過的道路條數的最小值,k爲一個常數且爲正整數。
所以Crash交給你一個簡單的任務:給出城市之間的道路,對於每一個城市,輸出這個城市的指標值,因爲指標值可能會很大,因此你只須要輸出這個數mod 10007的值。c++
輸入的第一行包括兩個正整數N和k。
下面有N-1行,每行兩個正整數u、v (1 ≤ u, v ≤ N),表示第u個城市和第v個城市之間有道路相連。這些道路保證能符合題目的要求。函數
輸出共N行,每行一個正整數,第i行的正整數表示第i個城市的指標值mod 10007的值。測試
5 2
1 2
1 3
2 4
2 5spa
10
7
23
18
18code
【數據規模和約定】
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);
}
}blog
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 7ip
根據套路\(n^{k}=\displaystyle\sum_{i=0}^{k}C_{n}^{i}S_2(k,i)\cdot i!\)。ci
\(S_2\)表示第二類斯特林數。而後咱們拿\(i\)當下標,記錄相同的\(i\)下,\(\sum C_{n}^{i}\)的值就好了。get
而後咱們作樹形DP,\(f[i][j]表示以i爲根的子樹中,\sum\limits_{v在i的子樹中}C_{dis(i,v)}^j\)。而後咱們轉移的時候,根據\(C_i^j=C_{i-1}^{j-1}+C_{i-1}^j\)獲得\(f[i][j]=\sum\limits_{u\in son_i}f[u][j-1]+f[u][j]\)。
代碼:
#include<bits/stdc++.h> #define ll long long #define mod 10007 #define N 50005 using namespace std; inline int Get() {int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();}while('0'<=ch&&ch<='9') {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}return x*f;} int n,k; ll fac[N]; ll ksm(ll t,ll x) { ll ans=1; for(;x;x>>=1,t=t*t%mod) if(x&1) ans=ans*t%mod; return ans; } struct load {int to,next;}s[N<<1]; int h[N],cnt; void add(int i,int j) {s[++cnt]=(load) {j,h[i]};h[i]=cnt;} int fa[N]; ll f[N][200]; ll sum[N][200]; void dfs(int v) { f[v][0]=1; for(int i=h[v];i;i=s[i].next) { int to=s[i].to; if(to==fa[v]) continue ; fa[to]=v; dfs(to); for(int j=1;j<=k;j++) (f[v][j]+=f[to][j]+f[to][j-1])%=mod; (f[v][0]+=f[to][0])%=mod; } } ll tem[200]; void solve2(int v) { for(int i=h[v];i;i=s[i].next) { int to=s[i].to; if(to==fa[v]) continue ; for(int j=1;j<=k;j++) { sum[to][j]=f[to][j]; tem[j]=(sum[v][j]-f[to][j]-f[to][j-1]+2*mod)%mod; } sum[to][0]=f[to][0]; tem[0]=sum[v][0]-f[to][0]; for(int j=1;j<=k;j++) (sum[to][j]+=tem[j]+tem[j-1])%=mod; sum[to][0]+=tem[0]; solve2(to); } } ll s2[200][200]; int main() { n=Get(),k=Get(); ll l=Get(),now=Get(),A=Get(),B=Get(),Q=Get(); for(int i=1;i<n;i++) { now=(now*A+B)%Q; ll tem=i<l?i:l; add(i-now%tem,i+1); } fac[0]=1; for(int i=1;i<=n;i++) fac[i]=fac[i-1]*i%mod; s2[0][0]=1; for(int i=1;i<=k;i++) { for(int j=1;j<=k;j++) { s2[i][j]=(s2[i-1][j-1]+j*s2[i-1][j]%mod)%mod; } } dfs(1); for(int i=0;i<=k;i++) sum[1][i]=f[1][i]; solve2(1); for(int i=1;i<=n;i++) { ll ans=0; for(int j=1;j<=k;j++) (ans+=sum[i][j]*s2[k][j]%mod*fac[j]%mod)%=mod; cout<<ans<<"\n"; } return 0; }