組合數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...