Description
给定整数N,求1<=x,y<=N且Gcd(x,y)为素数的
数对(x,y)有多少对.
Input
一个整数N
Output
如题
Sample Input
4
Sample Output
4
HINT
hint
对于样例(2,2),(2,4),(3,3),(4,2)
1<=N<=10^7
扫描二维码关注公众号,回复:
2864683 查看本文章
思路:假如n为11,求11以前的质数,以其中的一个 2为例
在[1,11]中,以gcd(x,y)==2 是2,4,6,8,10,的组合,若gcd(x,y)/2 ==1,等同于求(2/2,4/2,6/2,8/2,10/2)==(1,2,3,4,5)中到
5的一定互质的个数,即求phi[1-5]的值,因为x,y的限制仅为[1,n],个数为2*phi[1-5]-1,(2,2)只有一个会重复计算。
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<cmath>
#include<deque>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int M = 1e7 + 10;
ll n;
ll prime[M],phi[M];
bool vis[M];
void eular()
{
ll cnt=0;
memset(vis,true,sizeof(vis));
phi[1]=1;
for(ll i=2;i<M;i++)
{
if(vis[i])
{
prime[cnt++]=i;
phi[i]=i-1;
}
for(ll j=0;j<cnt && i*prime[j]<M;j++)
{
ll k=i*prime[j];
vis[k]=false;
if(i%prime[j]==0)
{
phi[k]=phi[i]*prime[j];
break;
}
else
phi[k]=phi[i]*(prime[j]-1);
}
}
for(int i=1;i<M;i++){
phi[i]+=phi[i-1];
//cout<<i<<" "<<phi[i]<<endl;
}
}
int main()
{
eular();
while(~scanf("%lld",&n))
{
ll ans=0;
for(ll i=2;i<=n;i++)
{
if(vis[i])
{
//cout<<phi[n/i]<<endl;
ans+=phi[n/i]*2-1;
}
}
printf("%lld\n",ans);
}
return 0;
}