盧卡斯 Lucas 定理

2021-07-24 10:07:12 字數 1788 閱讀 6255

之前有寫過一篇部落格是求組合數(取模)的兩種方法。那篇文章裡介紹的方法其實也還有侷限性,pascal打表由於記憶體的限制一般只用於求取1000以內的組合數,而使用逆元套公式的方法其實也只適用於求取的組合數 c(

n,m)

%p中,n 和 m均不大於要求的模數 p 。這樣就導致了乙個很尷尬的問題——如果要求取的組合數超過了模數p,這個時候有要怎麼辦呢。本人之前由於水平限制並沒有了解到這個問題,前幾天打玲瓏杯#round 4的時候被這個問題困擾了,經隊友提醒才知道有lucas定理這種東西。這裡就另寫一篇文章,其實是作為之前的「組合數取模的兩種方法」的乙個拓展篇。將這個問題一次性終結到底。

盧卡斯(lucas)定理設 p

為素數,a,

b∈n∗

,並且 a=

akpk

+ak−

1pk−

1+⋯+

a1p+

a0b=

bkpk

+bk−

1pk−

1+⋯+

b1p+

b0這裡 0

≤ai,

bi≤p

−1都是整數, i

=0,1

,2,⋯

,k. 則有 c

ba≡c

bkak

∗cbk

−1ak

−1∗⋯

∗cb0

a0(m

odp)

這裡還要宣告一點,本篇部落格的參考書籍為馮志剛版《初等數論》第37頁,下面給出原書的證明:

這個定理的意義就在於把

a 或者

b或者兩者均大於

p 的組合數 cb

a轉換為求解小於

p 的整數 ak

和 bk 的組合數 cb

kak 的乘積。

而對於 a0

,a1,

⋯,ak

可以通過秦九韶演算法: a=

(((⋯

(0∗p

+ak)

⋯)∗p

+a2)

∗p+a

1)∗p

+a0

逆向得到,即 a0

=(a/

p0)%

pa1=

(a/p

1)%p

a2=(

a/p2

)%p⋮

ak=(

a/pk

)%p

顯然,秦九韶的逆向演算法頁同樣適用於求解

b .

實際求解 cb

a時,只要 ai

和 bi 當中有乙個仍然大於

p ,就要繼續使用逆向的秦九韶演算法。但實際編寫**的過程,只需要遞迴即可:

ll lucas(ll a, ll b)

其中c(a, b)的函式在之前的文章求組合數(取模)的兩種方法敘述過了,這裡就不繼續贅述了。

現在,通過pascal打表的方法在 o(

1)的時間裡求得小範圍的組合數,用逆元的方法可以求取模數範圍內的組合數,在加上lucas定理,就可以求取任意範圍內的組合數了。

在實際運用的過程中,可以根據實際判斷哪種方法最適合,a,

b 的是乙個主導因素,同事,演算法的簡單性也是乙個主導因素。畢竟,越簡單的東西越不容易出錯。殺雞用牛刀不是不可以,但是你想過雞的感受麼。。。

以上です~

盧卡斯(Lucas)定理

c nm modp cn pm p cnm odpm modp modp c n m mod p c times c mod p cnm mo dp c n pm p cnmo dpmm odp modp p為素數 int qpow ll b,int n,int mod return res int...

盧卡斯定理Lucas

在數論中,lucas 定理用於快速計算 c m n p 即證明 c m n prod kc 其中 m i 為 m 的因式分解,n i 為 n 的因式分解,p 為質數。由 edward lucas 在1878年提出。證明 首先我們將 c i p 進行一下變式即 c i j frac 提出來乙個 fra...

盧卡斯定理 Lucas

當 p 為質數,1 le m le n 時,求組合數 c bmod 對於質數 p,有 begin c equiv c cdot c pmod end 其中 n p 和 m p 為整除。引理1 begin c equiv frac cdot c equiv 0 pmod end 引理1證明 begin...