題目鏈結
題目大意:給定乙個n個節點的樹,給它染色並且使得相鄰節點異色。問恰好用k種顏色的染色方案數
恰好k種不是很好求,因為我們很難保證每種顏色都用到,於是我們先考慮求最多k種顏色。
那麼就讓每個點和它的父親節點異色就可以了。
也就是k∗(
k−1)
n−
1k*(k-1)^
k∗(k−1
)n−1
那麼我們令f(i
)f(i)
f(i)
表示最多用i種顏色的染色方案數
g (i
)g(i)
g(i)
表示恰好用i種的染色方案數
那麼假設我們要最多用n種,那麼不妨從中隨意選其中i種,用且僅用這i種顏色染色。
也就是說f(n
)=∑i
=1nc
nig(
i)
f(n)=\sum_^^g(i)}
f(n)=∑
i=1n
cni
g(i
)然後就要用到二項式反演 g(n
)=∑i
=1n(
−1)n
−icn
if(i
)g(n)=\sum_^c_^f(i)}
g(n)=∑
i=1n
(−1
)n−i
cni
f(i)
f之前求出來了。問題就解決了。
#include
using
namespace std;
intread()
while
(s>=
'0'&&s<=
'9')
return x*f;
}const
long
long mod=
1000000007
;const
int n=
2600
;long
long
qpow
(long
long a,
long
long b)
int n,k;
long
long f[n]
;//最多用i種顏色的方案數
long
long calc[n]
,inv[n]
;void
init()
inv[n]
=qpow
(calc[n]
,mod-2)
;for
(int i=n-
1;i>=
0;i--)}
long
longc(
int i,
int j)
intmain()
ans=
(ans%mod+mod)
%mod;
printf
("%lld\n"
,ans)
;return0;
}
關於二項式反演,其實就是在恰好、最多(少)之間做轉換以達到簡化問題的作用。
最難的一步就是找到反演的原式子。
用到了「算兩次」的思想,用難算的表示好算的,然後用反演。
其實反演就是容斥,只不過有的時候直接用容斥不太好想。
二項式係數
任務描述 根據二項式定理,對於給定的二項式 a b 的n次方可以展開為c a的k次方 b的 n k 次方,k 0,1,2,n。現在要求出二項式的各個項的係數c。輸入 第一行包含乙個整數k 1 k 33 表示測試用例的個數。每個測試用例包含乙個整數n 1 n 33 輸出 按公式中的順序輸出各個二項式係...
二項式定理
在初等代數中,二項式定理 英語 binomial theorem 描述了二項式的冪的代數展開。根據該定理,可以將兩個數之和的整數次冪諸如 x y n 展開為類似 axby c 項之和的恒等式,其中b c均為非負整數且b c n。係數a是依賴於 n 和b的正整數。當某項的指數為0時,通常略去不寫。例如...
二項式反演
先從反演原理出發,假如存在兩個數列 f,g 我們知道 f n sum limits n a times g i 則 g n sum limits n b times f i 恆成立,那麼我們由 f 推出 g 的過程叫做反演。下面我們來 一下上面兩個式子恆成立的條件,將左邊帶入右邊,那麼有 begin...