組合數取模

2021-08-17 10:12:29 字數 2166 閱讀 3644

組合數c(m,n)表示在m個不同的元素中取出n個元素(不要求有序),產生的方案數。定義式:c(m,n)=m!/(n!*(m-n)!)(並不會使用latex qaq)。

根據題目中對組合數的需要,有不同的計算方法。

運用乙個數學上的組合恒等式(oi中稱之為楊輝三角):c(m,n)=c(m-1,n-1)+c(m-1,n)。

證明:

1.直接將組合數化為定義式暴力通分再合併。過程略。

2.運用組合數的含義:設m個元素中存在乙個「特殊」元素a,對從m個元素中選出n個元素進行分類討論。

第一種情況:n個元素中含有元素a,則只需在剩餘m-1個元素中選出n-1個元素即可。方案數為c(m-1,n-1)。

第二種情況:n個元素中不含元素a,則只需在剩餘m-1個元素中選出n個元素即可。方案數為c(m-1,n)。

這樣我們就得到了乙個與組合數有關的遞推式,初始化c(i,0)=1,隨後通過遞推以o(n2)的複雜度完成計算。均攤o(1)。

題意:給定乙個數k,然後給出t組m,n,對於每一組資料,詢問對於c(i,j)(0≤i≤n,0≤j≤min(i,m)),有多少個c(i,j)是k的倍數。

題解:70分做法:o(20002)預處理出所有組合數,然後每次暴力掃瞄c(i,j)判斷是否是k的倍數。然後機智地忘記取模(沒錯就是我233)

90分做法:在原有70分做法的預處理中加上取模,暴力掃瞄判斷是否為0。

100分做法:發現每次只是資料範圍改變,k和組合數都沒有改變,所以嘗試優化重複操作。

預處理+取模後,問題變為在整張組合數表中某個範圍內0的個數。我們將非0數置0,將0置1,問題轉化為矩陣和。用字首和預處理可以做到o(1)查詢。

#includeusing namespace std;

const int maxn=2000+10;

int c[maxn][maxn],d[maxn][maxn],s[maxn][maxn];

int t,n,m,k;

int main()

的期望,並將期望乘以(x + y)^nm 後對1e9+7取模。

資料範圍:

對於20% 的資料:n,m,x,y<=3

對於40% 的資料:n,m,x,y<= 70

對於70% 的資料:n,m,x,y<=5000

對於100% 的資料:n,m,x,y<=200000

題解:20%的直接暴力列舉每個格仔x次0,y次1,求出每次min並求和。

40%和70%好像可以用不同的dp來做,dp蒟蒻表示不會......

100分做法:先挖個坑在這 到時候寫乙個解題報告(雖然並不會寫部分分)

此時n,m一般可以出到max long long,簡單地o(n)預處理無法接受。就算n,m較小,p比n,m小時定義式中n!和m!在模p的意義下都為0,由於0不存在逆元,故直接用逆元計算會出錯。此時需要用lucas定理遞迴計算。

lucas定理:

c(n,m)%p=c(n/p,m/p)*c(n%p,m%p)。第一部分遞迴計算,第二部分用逆元處理。特別地,當遞迴過程中出現c(n,m),m>n的情況時,規定c(n,m)=0。

這個定理的另乙個表述:c(n,m)%p等價於將n,m寫成p進製,對n,m上的每一位進行組合數運算。

題解:裸的lucas。

#include#define ll long long

using namespace std;

const int maxn=2e5+10;

ll fac[maxn],infac[maxn],inv[maxn];

int n,m,p,t;ll ans;

ll f(int n,int m,int p)

return fac[n]*infac[n-m]%p*infac[m]%p;

}ll lucas(int n,int m,int p)

return f(n%p,m%p,p)*lucas(n/p,m/p,p)%p;

}int main()

{ int i,j;

cin>>t;

while(t--)

{cin>>n>>m>>p;

fac[0]=infac[0]=1;infac[1]=inv[1]=1;

for(i=1;i此時p不一定為質數,無法直接運用lucas定理求解,可以將p進行質因數分解,對每個質因子進行lucas,到時候再用中國剩餘定理合併。質因數分解建議採用pollard rho演算法。

組合數取模

複習了一下組合數取模,當然推薦檢視acdreamer的部落格啦,寫的確實好啦,自己把裡面的題目全a掉了。include include include include include include include using namespace std typedef long long ll l...

組合數取模

對於c n,m mod p。這裡的n,m,p p為素數 都很大的情況。就不能再用c n,m c n 1,m c n 1,m 1 的公式遞推了。這裡用到lusac定理 for non negative integers m and n and a prime p,the following congr...

Lucas 組合數取模

組合數取模就是求 cn mmod p cmn modp 的值,當然根據n,m,p n,m p 的取值範圍不同,採取的方法也不一樣。p p 比較大就只能乙個乙個算如 ll c one by one ll n,ll m 組合數乙個乙個算但是不是很大的要預先處理好階乘 數很大需要逆元 typedef lo...