Description
给定整数N,求1<=x,y<=N且Gcd(x,y)为素数的
数对(x,y)有多少对.
Input
一个整数N
Output
如题
Sample Input
4
Sample Output
4
HINT
hint
对于样例(2,2),(2,4),(3,3),(4,2)
1<=N<=10^7
Source
湖北省队互测
使
(
a
,
b
)
(a,b)
(a,b)为质数,可以转换成
(
a
,
b
)
=
1
(a,b)=1
(a,b)=1,然后是a,b同乘一个质数
假设
a
<
b
a<b
a<b,那么
(
a
,
b
)
=
1
(a,b)=1
(a,b)=1的方案数就是
ϕ
(
b
)
\phi(b)
ϕ(b),然后找出最大的质数
p
p
p,使
p
∗
b
≤
n
p*b\leq n
p∗b≤n
然后枚举b,p是单调下降的
O
(
n
)
O(n)
O(n)
#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 1e7+7;
int n;
int vis[N],phi[N],pri[N];
long long ans;
void getphi() {
phi[1] = 1;
for (int i = 2; i <= n; i++) {
if (!vis[i]) {
phi[i] = i-1;
pri[++*pri] = i;
}
for (int j = 1; j <= *pri && pri[j]*i <= n; j++) {
vis[i*pri[j]] = 1;
if (i % pri[j]) phi[i*pri[j]] = phi[i]*phi[pri[j]];
else {
phi[i*pri[j]] = pri[j]*phi[i];
break;
}
}
}
ans = *pri;
for (int i = 2, t = *pri; i <= n; i++) {
while (pri[t]*i > n && t > 0) t--;
if (!t) break;
ans+=2ll*t*phi[i];
}
}
int main() {
// freopen("2818.in", "r", stdin);
// freopen("2818.out", "w", stdout);
scanf("%d",&n);
getphi();
printf("%lld\n",ans);
}