题目描述
给定整数N,求
1≤N≤107
分析
首先筛出所有的素数。
我们考虑枚举素数p,统计满足gcd(x,y)=p的个数,等价于统计gcd(xp,yp)=1的个数,即统计[1,Np]以内满足互质的有序数对个数dN/p。
不难发现d1=1,di=di−1+2∗ϕ(i),也就是说,我们只要预处理出欧拉函数ϕ,就可以在O(n)之内求出d。
我们只需要用线性筛预处理出素数和欧拉函数,然后求
代码
#include <cstdio>
typedef long long lint;
const int N=10000010;
int n;
int vis[N];
int pri[N];
int phi[N];
lint d[N];
lint res;
int main(void)
{
scanf("%d",&n);
vis[0]=vis[1]=1,phi[1]=1;
for (int i=2;i<=n;i++)
{
if (!vis[i]) pri[++pri[0]]=i,phi[i]=i-1;
for (int j=1;j<=pri[0];j++)
{
if ((lint)i*pri[j]>n) break;
vis[i*pri[j]]=1;
if (i%pri[j])
phi[i*pri[j]]=phi[i]*phi[pri[j]];
else phi[i*pri[j]]=phi[i]*pri[j];
if (i%pri[j]==0) break;
}
}
d[1]=1;
for (int i=2;i<=n;i++)
d[i]=d[i-1]+phi[i]*2;
for (int i=1;i<=pri[0];i++)
res=res+d[n/pri[i]];
printf("%lld\n",res);
return 0;
}