题目描述
题解
这道题非常劲啊,让我这个傻逼证了半天。
首先设
gcd(a,b)=d
,
a′=a/t,b′=b/t
,那么
a′,b′
互质。
题目要求满足
(a+b)|ab
,这样的话就变成了
(a′+b′)d|a′b′d2
,即
(a′+b′)|a′b′d
。
又因为
(a′+b′)
与
a′b′
互质,可以得出
(a′+b′)|d
。
由
(a′+b′)d<=n
可知,
a′+b′<=n√
,即
a′+b′
一共只有
n√
种取值。
不妨设
a′+b′=k
,即
k
只有
kd<=n,d<=nk
,又因为
k|d
,那么
d
只有
又因为由
gcd(a′+b′,b′)=1
,可以推出
gcd(a′,b′)=1
,那么当
a′+b′=k
时,互质数对
a′,b′
的个数实际上为
φ(k)
种。
那么最终的答案即为
∑k=2n√nk2φ(k)
。
代码
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define LL long long
#define N 10000005
LL n,ans;
int prime[N],phi[N];
bool p[N];
void get_phi()
{
phi[1]=1;
for (int i=2;i<=10000000;++i)
{
if (!p[i])
{
prime[++prime[0]]=i;
phi[i]=i-1;
}
for (int j=1;j<=prime[0]&&i*prime[j]<=10000000;++j)
{
p[i*prime[j]]=true;
if (i%prime[j]==0)
{
phi[i*prime[j]]=phi[i]*prime[j];
break;
}
else phi[i*prime[j]]=phi[i]*(prime[j]-1);
}
}
}
int main()
{
get_phi();
scanf("%lld",&n);
for (LL i=2;i*i<=n;++i)
ans+=n/i/i*(LL)phi[i];
printf("%lld\n",ans);
}