眾所周知,二項式反演可以表示成
是乙個及其對稱的式子,常用的表示式是
網上有很多很好的證明,比如這個部落格,感覺容斥的證明比較形象,這裡就不多贅述了。
如果要求blabla恰好有k個blabla的時候,有時候會很難算,而求至多有k個blabla的時候會很好算
設 fi表示恰好的方案數, g i 表示至多的方案數,則有
根據二項式反演有
同樣有時候至少k個blabla的要更好求
設 f i 表示恰好的方案數,g i表示至少的方案數,則有
根據二項式反演有
cca的小球
轉恰好為至少即可
有n個連續的格仔和m種不同的染料,現在要用恰好對這n個格仔染色,每種染料至少染乙個格仔,並且任意相鄰的格仔顏色不同,問這樣選出染料並染色的合法方案數對109+7取模的值#include
using
namespace std;
typedef
long
long ll;
const ll mod=
1e9+7;
const
int n=
1e6+10;
int col[n]
;unordered_map<
int,
int>mp;
ll fac[n]
,mi[n]
;ll quick_pow
(ll x,ll y)
return ans;
}int
main()
ll res=0;
fac[0]
=1,mi[0]
=1;for
(int i=
1;i<=n;i++
) ll p=
quick_pow
(mi[num]
,mod-2)
;for
(int i=
0;i<=num;i++
)printf
("%lld\n"
,res)
;system
("pause");
return0;
}
我們先看只有k個的時候的種數,計算出結果只要乘上c(m,k)就是答案了。
我們先不管恰好是k個的限制,我們想成至多為k個的時候的答案,設為f(k)
易知:f( k )= k * ( k-1 ) n-1
那麼我們在恰好是k個的時候,也就是我們要求的答案,設為f(k),顯然這個不好求,但是我們可以找到f和f的關係:
則有
然後反演成:
就可以做了,最後別忘記乘上組合數
#include
#include
#include
#include
#include
#define ull unsigned long long
#define ll long long
#define mod 1000000007
#define maxn 1000005
using
namespace std;
ll fac[maxn]
,inv[maxn]
;ll p
(ll a,ll b)
return ans;
}void
init()
ll c
(int n,
int m)
int n=1;
ll g
(ll x)
intmain()
for(
int i=m;i>m-k;i--
) ans=ans*i%mod;
ans=ans*inv[k]
%mod;
printf
("case #%d: %lld\n"
,cal++
,ans);}
return0;
}
二項式反演
先從反演原理出發,假如存在兩個數列 f,g 我們知道 f n sum limits n a times g i 則 g n sum limits n b times f i 恆成立,那麼我們由 f 推出 g 的過程叫做反演。下面我們來 一下上面兩個式子恆成立的條件,將左邊帶入右邊,那麼有 begin...
二項式反演
形式與多步容斥相似,公式與多步容斥類似,多步容斥公式為 a 1 cup a 2 cup.cup a n sum limits a i sum limits n 1 ig i g n sum limits n 1 if i 顯然這兩個公式是等價,也是相互推導的關係,因此我們得到了二項式反演的形式1 形...
Kings Colors 二項式反演
題目鏈結 題目大意 給定乙個n個節點的樹,給它染色並且使得相鄰節點異色。問恰好用k種顏色的染色方案數 恰好k種不是很好求,因為我們很難保證每種顏色都用到,於是我們先考慮求最多k種顏色。那麼就讓每個點和它的父親節點異色就可以了。也就是k k 1 n 1k k 1 k k 1 n 1 那麼我們令f i ...