容斥原理是大學離散數學裡的應用,就算沒學過也能理解。畢竟,在程式設計師眼中,排列組合是不會有多麼離散的。
題目直接看題
devu有n個盒子,第i個盒子中有ai枝花。題解同乙個盒子內的花顏色相同,不同盒子內的花顏色不同。
devu要從這些盒子中選出m枝花組成一束,求共有多少種方案。
若兩束花每種顏色的花的數量都相同,則認為這兩束花是相同的方案。
結果需對109+7取模之後方可輸出。
輸入格式
第一行包含兩個整數n和m。
第二行包含n個空格隔開的整數,表示a1,a2,…,an。
輸出格式
輸出乙個整數,表示方案數量對109+7取模後的結果。
資料範圍
1≤n≤20 ,
0≤m≤10^14,
0≤ai≤10^12
輸入樣例:
3 51 3 2
輸出樣例:
3
簡化分析:
抽象題意,就是在求n個盒子中,有重複的選取m。。
是一道明顯的有重複組合問題,但是這道題加了限制以此增加難度,同時資料量很大,m達到了10^14
下面看一下簡化版。
假設,每個盒子中球的數量是無限的。
那麼給如何求選取方案呢?
可以這樣:
假設xi為第i個盒子中選出來的球。
那麼滿足等式:x1+x2+x3+..
..xi...+xn=m
(1)使用離散數學中有重複組合計數就直接得出答案,
(2)另一種思考模式,可以轉化一下,求該等式解的數量,但是注意到xi可能為0,於是處理等式每個xi都加1,
x1+x2+x3+..
..xi...+xn=m+n
此時xi都為正整數,這就變得簡單了。
使用隔板法,(在m+n-1個縫隙裡放入n-1個隔板)
答案就是c(m+n-1,n-1)
;
簡化就很舒服,但是回到現實,每個盒子裡是有數量限制的。
這也很明顯,我們使用排雜法
那怎麼排雜呢?
我們需要滿足的條件是x1<=a1,x2<=a2,x3<=a3……xn<=anx1<=a1,x2<=a2,x3<=a3……xn<=an
我們只需要考慮理想情況c(m+n-1,n-1)再減去所有不合法的情況。
不合法的情況分為很多種,假設s1表示x1>a1的不合法情況,以此類推,si表示xi>ai的不合法情況,那麼很明顯。主角登場,容斥原理。不合法就可以表示為s1⋃s2⋃s3……⋃sn的交集
注意,每一種組合就是該項不合法的所有情況,比如s1=c(m+n−1−(ai+1),n−1)
那麼結果展開就是
將其展開就是:
c(m+n-1,n-1)−|s1|−|s2|−……|s3|+|s1⋂s2|+……−|s1⋂s2⋂s3|−...
複雜度下次補上。。
思路簡化,就是通過二進位制列舉,奇數就減去,偶數就加。求一遍組合數取模
。其中用到費馬小引理求逆元。
看**
#include
#include
#include
using
namespace std;
typedef
long
long ll;
const
int n=
25,mod=
1e9+7;
ll a[n]
;ll down =1;
//求快速冪
ll qmin
(ll a,ll k)
return res;
}//求組合數c(a,b)
ll c
(ll a,ll b)
intmain()
//預處理(n-1)!的逆元
down=
qmin
(down,mod-2)
;
ll res=0;
for(
int i=
0;i<
1
(res+
c(a,b)
*fg)
%mod;
//容斥原理求組合數
}
cout<<
(res+mod)
%mod
}
總結 容斥原理與反演
這個是個好東西.實際上,容斥和反演沒有什麼區別。目錄 題解 cf997c sky full of stars 題解 cf451e devu and flowers 容斥 題解 cjoi2019 登峰造雞境 prufer序列 斯特林數 題解 cf559c c.gerald and giant ches...
容斥原理演算法總結 bzoj 2986 2839
容斥原理是乙個從小學就開始學習的演算法。但是很多難題現在都覺得做的十分吃力。容斥原理大概有兩種表現形式,一種是按照倍數進行容斥,這個東西直接用莫比烏斯函式就可以了。include include include include using namespace std define maxn 2001...
容斥原理 數論
兩個集合的容斥關係公式 a b a b a b a b 重合的部分 三個集合的容斥關係公式 a b c a b c a b b c c a a b c 最後可以推廣到n個集合,集合裡的元素為奇數則加,偶數減 hdu 4135 很簡單,直接求出所有的質因子,然後容斥解決 author crystal ...