Description
给定整数N,求1<=x,y<=N且Gcd(x,y)为素数的
数对(x,y)有多少对.
Input
一个整数N
Output
如题
Sample Input
4
Sample Output
4
HINT
对于样例(2,2),(2,4),(3,3),(4,2)
1<=N<=10^7
题解:
首先求出phi的值,然后做一个前缀和。
然后枚举小于n的每一个质数。
所有<=n/p[i]的互质的两个数乘上p[i]都小于n且gcd为p[i];
因为已经做前缀和所以直接加上phi[n/p[i]]*2-1即可。
代码
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#define N 10001
#define M 1000001
#define ll long long
ll sum[10000005],ans;
bool mark[10000005];
int phi[10000005],p[10000005];
int n,tot;
using namespace std;
inline int read()
{
int x=0;char ch=getchar();
while (ch<'0'||ch>'9') ch=getchar();
while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
return x;
}
int main()
{
n=read();phi[1]=1;
for (int i=2;i<=n;i++)
{
if (!mark[i]) phi[i]=i-1,p[++tot]=i;
for (int j=1;j<=tot&&i*p[j]<=n;j++)
{
mark[i*p[j]]=1;
if (i%p[j]==0)
{
phi[i*p[j]]=phi[i]*p[j];
break;
}
phi[i*p[j]]=phi[i]*(p[j]-1);
}
}
for (int i=1;i<=n;i++)
sum[i]=sum[i-1]+phi[i];
for (int i=1;i<=tot;i++)
ans+=sum[n/p[i]]*2-1;
printf("%lld",ans);
return 0;
}