一.暴力法
複雜度o(n)
適用:小資料,n=60可用
**:
f[0]
[0]=
1;for(
int i=
1;i<=n;i++
)for
(int j=
0;j<=i;j++)if
(j) f[i]
[j]=f[i-1]
[j]+f[i-1]
[j-1];
else f[i]
[j]=f[i-1]
[j];
二.逆元法
複雜度o(nlog(n))
適用:m小於p;
思路:把除以乙個數變成乘乙個數的逆元。
逆元求法
【對於正整數a和p,如果有ax≡1(mod p),那麼把這個同餘方程中x的小正整數解叫做a的逆元。由費馬小定理知,當a與p互質時,a^(p-1) %p=1。所以當p是質數時,a的逆元為a^(p-2)。】
**:1)只需求一次大組合數時可使用
ll power
(ll a,ll b)
return ans%mod;
}ll c
(ll n,ll m)
ll ans=1;
n=min(n,m-n)
;for
(ll i=
1;i<=n;i++
)for
(ll i=m-n+
1;i<=m;i++
)return ans;
}
2)求多次,優化一下,預處理階乘和階乘的逆元
ll f[n]
,inv[n]
;ll pow_mod
(ll a,ll b,ll c)
return ans%c;
}inline ll c
(int k,
int n)
void
init()
inv[n-1]
=pow_mod
(f[n-1]
,mod-
2,mod)
;//逆推預處理階乘的逆元
for(
int i = n-
2; i >=
0; i--
)return
;}
三.lucas定理
複雜度:o(n*log(n)*log(n/mod))
適用:m>p,m,n很大時
盧卡斯(lucas)定理的定義
再運用秦九韶演算法可求得ai,bi;
**:
ll lucas
(ll a,ll b)
配合逆元法使用即可 組合數 求組合數的幾種方法總結
求c n,m mod的方法總結 1.當n,m都很小的時候可以利用楊輝三角直接求。c n,m c n 1,m c n 1,m 1 2.利用乘法逆元。乘法逆元 a b mod a b mod 2 mod為素數。逆元可以利用擴充套件歐幾里德或尤拉函式求得 1 擴充套件歐幾里德 b x p y 1 有解,x...
求素數的三種方法
具體篩法是 先把n個自然數按次序排列起來。1不是質數,也不是合數,要划去。第二個數2是質數留下來,而把2後面所有能被2整除的數都劃去。2後面第乙個沒劃去的數是3,把3留下,再把3後面所有能被3整除的數都劃去。3後面第乙個沒劃去的數是5,把5留下,再把5後面所有能被5整除的數都劃去。這樣一直做下去,就...
求Fibonacci數列的三種方法
fibonacci數列 0,1,1,2,3,5,8,13。第一招 遞推法 includeint f 47 int main 第二招 不斷變換初始 include int main if n 1 n 2 puts 1 else if n 0 puts 0 else printf d n f3 retu...