1e14以内的素数间隔最大不超过700(我也不会证明,网上看的)
威尔逊定理:https://blog.csdn.net/m0_50623076/article/details/109894993
p-1!≡-1(mod(p))
化为p-1p-2……Q+1Q!≡-1modp=(p-1)(modp)
只需要根据费马小定理求出(p-1)….(Q+1)的逆即可。ap-1 ≡1(mod(p))
代码:
#include<algorithm>
#include<iostream>
#include<cstring>
#include<string>
#include<cstdlib>
#include<map>
#include<cmath>
#include<vector>
#include<cstdio>
using namespace std;
typedef long long ll;
const int maxn = 1e6+50;
ll p;
bool isprime(ll x){
for(ll i = 2;i*i <= (x);i++)
if(x%i == 0) return false;
return true;
}
ll mul(ll a,ll b){//a*b慢速乘
ll ans = 0;
while(b){
if(b%2 == 1) ans = (ans+a)%p;
b>> =1;
a = (a+a)%p;
}
return ans;
}
ll qpow(ll a,ll b){//a^b快速幂
ll ans = 1;
while(b){
if(b&1) ans = mul(ans,a);
b >>= 1;
a = mul(a,a);
}
return ans;
}
int main(){
int t;
cin >> t;
while(t--){
cin >> p;
ll n = p-1;
ll ans = 1;
while(!isprime(n)) n--;
for(ll i = p-1;i >= n+1;i--) ans = mul(ans,i);
//乘出来(p-1)到(q+1) q这里用n
ans = qpow(ans,p-2);
//变成逆
ans = mul(ans,p-1);
//左边本身就有的
cout << ans << endl;
}
return 0;
}