题目描述
给定整数
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;
}