威爾遜定理 k p

2022-06-08 21:15:33 字數 1955 閱讀 6679

傳送門

給你乙個素數p,讓你求 k!%p, 其中k為比p小的整數裡最大的素數。例如p=5,則k=3。p=11,則k=7。 k! = k*(k-1)*······*2*1;

input第一行包含乙個整數 t(1<=t<=10) 表示測試樣例的個數.

接下來有t行,每行包含乙個素數 p (1e9≤p≤1e14)

output對於每個測試樣例,輸出乙個整數k!%p,代表答案

sample input

1

1000000007

sample output

328400734

因為兩個素數之間的間隔不會超過300,我們從p-1開始乙個個查驗找q。再把(p-1)乘上[q,p-1]的逆元即可。

注意因為數很大,所有涉及乘的地方都要用快速乘。

威爾遜定理:在初等數論中,威爾遜定理給出了判定乙個自然數是否為素數的充分必要條件。

即:當且僅當p為素數時:( p -1 )! ≡ -1 ( mod p ),但是由於階乘是呈**增長的,其結論對於實際操作意義不大。

也就是說(p-1)!mod p == p-1;

//威爾遜定理是(p-1)!modp==p-1

//q p

//(q-1)!modp=-1 ==> (p-1)!mod p == p-1;

//q!*(q+1)*(q+2)....(p-1)==(p-1)!

//q!(mod p)==(p-1)!/[(q+1)*(q+2)*(q+3)....(p-1)](mod p)

//q!(mod p)==(p-1)/(q+1)*(q+2)*(q+3)*...*(p-1))(mod p)

因為這裡的數乘法太大了,所以用的快速乘法
#include#include

using

namespace

std;

typedef

long

long

ll;const

int maxn=1e7+100

; int

prime[maxn];

bool

biaoji[maxn];

int cnt=0

;void

inint()}}

}bool

judge(ll x)

}return1;

} ll mul(ll a,ll b,ll mod)

a=(a+a)%mod;

b>>=1

; }

return ans%mod;

}ll qpow(ll a,ll b,ll mod)

a=mul(a,a,mod)%mod;

b>>=1

; }

return ans%mod;

} //

威爾遜定理是(p-1)!modp==p-1

//q p

//(q-1)!modp=-1 ==> (p-1)!mod p == p-1;

//q!*(q+1)*(q+2)....(p-1)==(p-1)!

//q!(mod p)==(p-1)!/[(q+1)*(q+2)*(q+3)....(p-1)](mod p)

//q!(mod p)==(p-1)/(q+1)*(q+2)*(q+3)*...*(p-1))(mod p)

intmain()

}ll ans=p-1

;

for(ll i=q+1;i<=p-1;i++)

cout

}}

威爾遜定理

而要解這個問題,使用窮舉或暴搜的方法顯然不可取。若要優雅而巧妙地解決這個問題,就需要用到乙個關於素數的著名結論 威爾遜定理 wilson s theorem 十八世紀中葉,一位英國法官約翰 威爾遜爵士,發現了數論中一種極為罕見的關係 取從1到某個質數所有連續正整數的乘積,例如從1乘到11,即11的階...

Fansblog 威爾遜定理

題意 給乙個質數 p 找小於 p 的最大質數 q 並求 q modp p,q epsilon 10 9,10 題解 威爾遜定理 乙個數 n 若是質數,則有 n 1 equiv n 1 mod n 於是可以先令 ans p 1 再對 p 1 到 q 的數對 p 求逆元。p 到 q 之間的距離不會超過3...

威爾遜定理證明

威爾遜定理 當 p 1 1 mod p 時,p 為素數。p p 1 1 即 p 1 equiv p 1 equiv 1 mod p 證明 靜下心看 先假設集合 m 集合 n 任取乙個 a in m a 一定與 p 互質。再假設乙個集合 s a cdot n 對於 forall x in n x 一定...