题目链接:
http://132.232.5.128:666/problem/110
题目大意:
对于一个整数对 ( a , b ) (a,b) (a,b),若满足 a + b ≤ n a+b \leq n a+b≤n且 a + b a+b a+b是 a × b a \times b a×b的因子,则称为神奇的数对。问这样的数对共有多少。
题目分析:
1.整除一类的题,我们很快能想到的就是
G
C
D
GCD
GCD,我们可以利用
g
c
d
gcd
gcd将式子化简,
a
+
b
∣
a
×
b
a+b|a \times b
a+b∣a×b,设
d
=
g
c
d
(
a
,
b
)
d=gcd(a,b)
d=gcd(a,b),
a
′
=
a
d
a'=\frac{a}{d}
a′=da,
b
′
=
b
d
b'=\frac{b}{d}
b′=db。那么
(
a
′
+
b
′
)
×
d
∣
a
′
×
b
′
×
d
×
d
(a'+b') \times d|a' \times b' \times d \times d
(a′+b′)×d∣a′×b′×d×d,所以
(
a
′
+
b
′
)
∣
a
′
×
b
′
×
d
(a'+b')|a' \times b' \times d
(a′+b′)∣a′×b′×d,而根据辗转相除法,
g
c
d
=
(
a
′
+
b
′
,
a
′
)
=
g
c
d
(
a
′
+
b
′
,
b
′
)
=
g
c
d
(
a
′
+
b
′
,
a
′
×
b
′
)
=
1
gcd=(a'+b',a')=gcd(a'+b',b')=gcd(a'+b',a' \times b')=1
gcd=(a′+b′,a′)=gcd(a′+b′,b′)=gcd(a′+b′,a′×b′)=1。所以我们得到了
(
a
′
+
b
′
)
∣
d
(a'+b')|d
(a′+b′)∣d。
2.因为
(
a
′
+
b
′
)
×
d
≤
n
(a'+b') \times d \leq n
(a′+b′)×d≤n,所以
(
a
′
+
b
′
)
≤
n
(a'+b') \leq \sqrt n
(a′+b′)≤n。若
(
a
′
+
b
′
)
=
k
(a'+b')=k
(a′+b′)=k,那么合法的
d
d
d就有
n
/
k
2
n/k ^ 2
n/k2个。而合法的
(
a
′
,
b
′
)
(a',b')
(a′,b′)就有
ϕ
(
k
)
\phi(k)
ϕ(k)个,所以答案就要加上
n
/
k
2
×
ϕ
(
k
)
n/k ^ 2 \times \phi(k)
n/k2×ϕ(k)。
3.于是我们枚举一下所有的
k
k
k就行了。
正解程序:
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cmath>
using namespace std;
typedef long long ll;
const ll maxn=10000010;
ll n,ans;
ll count1=0,prime[maxn],phi[maxn];
bool vis[maxn];
int main()
{
scanf("%lld",&n);
ll Max=sqrt(n);
for(ll i=2;i<=Max;i++)
{
if(!vis[i])
{
prime[++count1]=i;
phi[i]=i-1;
}
for(ll j=1;j<=count1 && i*prime[j]<=Max;j++)
{
vis[i*prime[j]]=true;
if(i%prime[j]==0)
{
phi[i*prime[j]]=phi[i]*prime[j];
break;
}
phi[i*prime[j]]=phi[i]*(prime[j]-1);
}
ans+=n/i/i*phi[i];
}
printf("%lld\n",ans);
return 0;
}