给定整数 N N N ,求 1 ≤ x , y ≤ N 1≤x,y≤N 1≤x,y≤N 且 G C D ( x , y ) GCD(x,y) GCD(x,y) 为素数的数对 ( x , y ) (x,y) (x,y) 有多少个
考虑
1
1
1~
N
N
N 内的每个质数
p
i
p_i
pi, 都有
gcd
(
x
,
y
)
=
p
i
\gcd(x, y) = p_i
gcd(x,y)=pi
对该式化简有
gcd
(
x
p
i
,
y
p
i
)
=
1
\gcd(\frac{x}{p_i} , \frac{y}{p_i}) = 1
gcd(pix,piy)=1
不妨设
1
≤
x
<
y
≤
N
1 \leq x < y \leq N
1≤x<y≤N,而
y
<
x
y < x
y<x 的情况仅需要乘
2
2
2 即可
那么对每个
p
i
p_i
pi 有
1
≤
x
p
i
<
y
p
i
≤
N
p
i
1 \leq \frac{x}{p_i} < \frac{y}{p_i} \leq \frac{N}{p_i}
1≤pix<piy≤piN
也就是说,对每个
y
p
i
\frac{y}{p_i}
piy 我们要求与他互质的个数,即对每个
p
i
p_i
pi 求
∑
j
=
1
⌊
N
p
i
⌋
φ
(
j
)
\sum\limits_{j = 1} ^{\lfloor \frac{N}{p_i}\rfloor} \varphi(j)
j=1∑⌊piN⌋φ(j)
再去想当
j
=
1
j = 1
j=1 的时候,也就是
y
=
p
i
y = p_i
y=pi,此时也必然有
x
=
p
i
x = p_i
x=pi,而两个相等的数只能算一种,因此最后答案
∑
i
=
1
c
n
t
p
(
2
×
∑
j
=
1
⌊
N
p
i
⌋
φ
(
j
)
−
1
)
\sum\limits_{i = 1} ^{cntp} (2 \times \sum\limits_{j = 1} ^{\lfloor \frac{N}{p_i}\rfloor} \varphi(j) - 1)
i=1∑cntp(2×j=1∑⌊piN⌋φ(j)−1)
对于后一个和式可用前缀和在
O
(
n
)
O(n)
O(n) 内算出
CODE
#include <iostream>
#define ll long long
using namespace std;
const int maxn = 1e7 + 10;
int npri[maxn];
int pri[maxn], eurl[maxn];
ll sum[maxn];
int cntp = 0;
void geteurl(int n){
eurl[1] = 1;
for (int i = 2; i <= n; i++){
if (!npri[i]){
pri[++cntp] = i;
eurl[i] = i - 1;
}
for (int j = 1; i * pri[j] <= n; j++){
npri[pri[j] * i] = 1;
if (i % pri[j] == 0){
eurl[i * pri[j]] = eurl[i] * pri[j];
break;
}
eurl[i * pri[j]] = eurl[i] * (pri[j] - 1);
}
}
}
int main(){
geteurl(maxn);
for (int i = 1; i <= maxn; i++) sum[i] = sum[i - 1] + eurl[i];
int n;
cin >> n;
ll ssum = 0;
for (int i = 1; i <= cntp; i++){
if (pri[i] > n) break;
ssum += 2 * sum[n / pri[i]] - 1;
}
cout << ssum;
return 0;
}