又來做了一次。。
之前寫得實在是太差了,這次寫好點吧。。
這裡介紹用斯特林數展開的方法
如果不會的可以先看看這裡
我們知道xn=
∑k=0
ns(n
,k)∗
k!∗c
(x,k
)x^n=\sum_^ns(n,k)*k!*c(x,k)
xn=∑k=
0ns
(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條道路連線...