题目链接
https://ac.nowcoder.com/acm/contest/12478/E
解题思路
1.当我们求解分数的幂时,可以利用`逆元`来求解;
2.用线性筛求出范围内的所有素数,再遍历求出孪生素数的个数prim_num;
3.化简下 primnum/t*(t-1)/2,化简得 2*prim_num / t*(t-1)
4.再用快速幂求解即可;
代码展示
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll maxn=1e7;
const ll inf=1e9+7;
/*
*/
//非递归快速幂
ll qpow(ll a,ll b,ll c){//a^b c是mod
ll ans=1,t=a;
while(b>0){
if(b&1) ans=((ans%c)*(t%c))%c;
t=((t%c)*(t%c))%c;
b>>=1;
}
return ans%c;
}
ll prim[maxn];
bool vis[maxn];
void qprim(){
memset(prim,0,sizeof(prim));
memset(vis,0,sizeof(vis));
for(int i=2;i<=maxn;i++){
if(!vis[i])
prim[++prim[0]]=i;
for(int j=1;j<=prim[0]&&i*prim[j]<=maxn;j++){
vis[i*prim[j]]=1;
if(i%prim[j]==0)//??
break;
}
}
}
int main(){
ll n;
cin>>n;
qprim();
while(n--){
ll t;
cin>>t;
ll prim_num=0;
for(int i=2;i<=prim[0]&&prim[i]<=t;i++){
if(prim[i]-prim[i-1]==2)
prim_num+=1;
}
//cout<<prim_num<<endl;
// ll f1=(((t*(t-1))%inf)*qpow(2ll,inf-2,inf))%inf;
// ll f2=(prim_num*qpow(f1,inf-2,inf))%inf;
ll f2=((2*prim_num)%inf*qpow((t*(t-1))%inf,inf-2,inf))%inf;
cout<<f2<<endl;
}
return 0;
}
总结
1.逆元确实在算法竞赛中很重要,尤其是和费马小定理等结合;
2.快速幂在使用时要注意mod使用,千万不能遗漏;