bzoj 2159 Crash 的文明世界

2021-09-07 19:24:31 字數 2227 閱讀 9502

又來做了一次。。

之前寫得實在是太差了,這次寫好點吧。。

這裡介紹用斯特林數展開的方法

如果不會的可以先看看這裡

我們知道xn=

∑k=0

ns(n

,k)∗

k!∗c

(x,k

)x^n=\sum_^ns(n,k)*k!*c(x,k)

xn=∑k=

0n​s

(n,k

)∗k!

∗c(x

,k)因此,如果想知道答案,其實就是要知道對於每乙個k

kk,c(x

,k

)c(x,k)

c(x,k)

的和然後,你會發現,這題邊權是1,這個很關鍵

我們知道組合數的性質cnm

=cn−

1m+c

n−1m

−1

c_n^m=c_^m+c_^

cnm​=c

n−1m

​+cn

−1m−

1​因此,不難想到怎麼求1的答案

我們對於每乙個節點dp乙個值f[s

on][

k]

f[son][k]

f[son]

[k],表示他子樹裡面所有點到他的c(x

,k

)c(x,k)

c(x,k)

的答案那麼不難得到f[f

a][k

]=f[

son]

[k]+

f[so

n[k−

1]

f[fa][k]=f[son][k]+f[son[k-1]

f[fa][

k]=f

[son

][k]

+f[s

on[k

−1]就這麼dp上去就可以得到1的答案了

然後再順著dp下來,用父親更新兒子的答案

也就是,先把兒子對父親的貢獻去掉,就相當於父親的資訊是兒子的子樹了,用同樣的方法轉移即可

實現也很簡單,時間複雜度o(n

k)

o(nk)

o(nk)

因為沒有看題。。特殊的讀入不知道wa了很多發。。

code:

#include

#include

#include

#include

using

namespace std;

const

int mod=

10007

;const

int n=

50005

;const

int k=

155;

struct qq

e[n*2]

;int num,last[n]

;int n,k;

void init (

int x,

int y)

int s[n]

[k];

int f[n]

[k];

//子樹裡面的答案

int jc[k]

;void dfs (

int x,

int fa)

}int calc (

int x)

int d[k]

;void dfs1 (

int x,

int fa)

}int

main()

s[0][

0]=1

;for

(int u=

1;u<=k;u++

)for

(int i=

1;i<=u;i++

) s[u]

[i]=

(s[u-1]

[i-1

]+s[u-1]

[i]*i%mod)

%mod;

jc[0]

=1;for

(int u=

1;u<=k;u++

) jc[u]

=jc[u-1]

*u%mod;

dfs(1,

0);dfs1(1

,0);

for(

int u=

1;u<=n;u++

)printf

("%d\n"

,calc

(u))

;return0;

}

BZOJ2159 Crash 的文明世界

這篇寫差分表和斯特林數介紹的不錯 這題就是要計算這個東西 s i j 1n dist i,j ks i j 1nd ist i,j k這個東西很難維護,我們把di st i j k d is t i,j k拆一下s u v kj 0d u,v d u,v j s u v j 0 kd u v d u...

BZOJ 2159 Crash 的文明世界

記得去年暑假集訓的時候本來想了乙個動態點分的做法的,然後寫道一半因為某些不知名原因就沒寫了,然後就一直放著,然後發現斯特林反演真nm好寫 首先考慮用關於冪的斯特林反演 m n sum m left times i times c m i 套上去就是 ans x sum n dis i,x k sum...

bzoj 2159 Crash 的文明世界

crash小朋友最近迷上了一款遊戲 文明5 civilization v 在這個遊戲中,玩家可以建立和發展自己的國家,通過外交和別的國家交流,或是通過戰爭征服別的國家。現在crash已經擁有了乙個n個城市的國家,這些城市之間通過道路相連。由於建設道路是有花費的,因此crash只修建了n 1條道路連線...