标签:prim spl absolute min round exgcd log abs content
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=6608
#include<bits/stdc++.h>
using namespace std;
//( p -1 )! ≡ -1 =p-1( mod p ) 当p为素数时
long long const n=1e7+100;
typedef long long ll;
ll prime[n];
ll p,q,cntprime,ans;
bool flag[n];
void exgcd(ll a,ll b,ll &x,ll &y){//扩展欧几里得求逆元快一点,用费马小定理 a^(p-2) 由于p太大,容易超时
if(!b){x=1;y=0;}
else {exgcd(b,a%b,y,x);y-=x*(a/b);}
}
ll getinv(ll a){//求q!%p 相当于= (p-1)!/(p-1)/(p-2)...(q+1)%p 用逆元
ll x,y;
exgcd(a,p,x,y);
while(x<0)x+=p;
return x;
}
ll mul(ll a,ll b){//快速乘 防止longlong 相乘会炸longlong
ll ret=0;
for(;b;b>>=1,a=(a<<1)%p)
if(b&1) ret=(ret+a)%p;
return ret%p;
}
void getans(){
ans=p-1;
for(ll i=p-1;i>q;i--){
ans=mul(getinv(i),ans);//用快速乘
}
}
void getprime(){//判断1e14内的质数,只需看有无1e7内的质数
cntprime=0;
for (ll i = 2; i <= 1e7; i++)
{
if (!flag[i]) prime[++cntprime] = i;
for (int j = 1; j <= cntprime && prime[j] * i <= n; j++)
{
flag[i * prime[j]] = true;
if (i % prime[j] == 0)
break;
}
}
}
void getq(){//素数密度分布,素数分布的比较密集 cout<<p-q<<endl;
//可以从大到小枚举,判断是否为质数,出现的比较快
bool ok;
for(ll i=p-2;i>=2;i--){
ok=false;
ll z=(long long)sqrt(i);
for(int j=1;j<=cntprime&&prime[j]<=z;j++)if(i%prime[j]==0){ok=true;break;}
if(!ok){q=i;return ;}
}
}
int main(){
int t;
scanf("%d",&t);
getprime();
while(t--){
scanf("%lld",&p);
getq();
getans();
cout<<ans<<endl;
}
return 0;
}
[hdu-6608] Fansblog 威尔逊定理 质数的密度分布 2019 多校 3
标签:prim spl absolute min round exgcd log abs content
原文地址:https://www.cnblogs.com/conver/p/11273386.html