题 意 题意 题意
给 定 n , 求 ∑ i = 1 n ∑ j = 1 n [ g c d ( i , j ) = k ] , k i s p r i m e 给定n,求\sum_{i=1}^{n} \sum_{j=1}^{n} [gcd(i, j) = k], k\ is \ prime 给定n,求i=1∑nj=1∑n[gcd(i,j)=k],k is prime
题 解 题解 题解
原 式 = ∑ k ∑ i = 1 n ∑ j = 1 n [ g c d ( i , j ) = k ] = ∑ k ∑ i = 1 n / k ∑ j = 1 n / k [ g c d ( i , j ) = 1 ] = ∑ k ( 2 ⋅ ∑ i = 1 n / k ϕ ( i ) ) + 1 \begin{aligned} \qquad\qquad\qquad 原式 &=\sum_{k} \sum_{i=1}^{n} \sum_{j=1}^{n} [gcd(i, j) = k] \\ &= \sum_{k} \sum_{i=1}^{n/k} \sum_{j=1}^{n/k} [gcd(i, j) = 1] \\ &= \boxed{\sum_{k} (2 \cdot \sum_{i=1}^{n/k} \phi(i)) + 1}\\ \end{aligned} 原式=k∑i=1∑nj=1∑n[gcd(i,j)=k]=k∑i=1∑n/kj=1∑n/k[gcd(i,j)=1]=k∑(2⋅i=1∑n/kϕ(i))+1
枚 举 素 数 k , 预 处 理 处 欧 拉 函 数 前 缀 和 , 计 算 答 案 枚举素数k,预处理处欧拉函数前缀和,计算答案 枚举素数k,预处理处欧拉函数前缀和,计算答案
代 码 代码 代码
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 10000010;
int n, phi[N], p[N];
LL sum[N];
int tot;
bool used[N];
//预处理出素数 欧拉函数 欧拉函数前缀和
void init(LL n) {
phi[1] = 0;
for (int i = 2; i <= n; i++) {
if (!used[i]) {
phi[i] = i - 1;
p[++tot] = i;
}
for (int j = 1; p[j] * i <= n; j++) {
used[p[j] * i] = true;
if (i % p[j] == 0) {
phi[i * p[j]] = phi[i] * p[j];
break;
}
phi[i * p[j]] = phi[i] * (p[j] - 1);
}
}
for (int i = 1; i <= n; i++) sum[i] = sum[i-1] + phi[i];
}
LL cal(LL x) {
LL res = 0;
for (int i = 1; i <= tot; i++) {
int t = x /p[i];
res += 2L * sum[t] + 1;
}
return res;
}
int main() {
int x;
cin >> x;
init(x);
cout << cal(x) << endl;
return 0;
}