Luogu P1390 公约数的和

\[\texttt{Description} \]

给出 \(n\),求 \(\sum\limits_{i = 1}^n\sum\limits_{j=i+1}^n \gcd(i,j)\)

\[\texttt{Solution} \]

注意到:

\[\sum\limits_{i = 1}^n\sum\limits_{j = i + 1}^n \gcd(i, j) = \frac{\sum\limits_{i = 1}^n\sum\limits_{j = 1}^n \gcd(i, j) - \sum\limits_{i = 1}^n \gcd(i,i)}{2} = \frac{\sum\limits_{i = 1}^n\sum\limits_{j = 1}^n \gcd(i, j) - \frac{n \cdot (n + 1)}{2}}{2} \]

于是问题转化为如何求出 \(\sum\limits_{i = 1}^n\sum\limits_{j = 1}^n \gcd(i, j)\)

考虑枚举 \(d = \gcd(i, j)\),则式子化为:

\[\sum\limits_{d = 1}^n d \cdot \sum\limits_{i = 1}^n\sum\limits_{j = 1}^n [\gcd(i,j) = d] \]

\[\sum\limits_{d = 1}^n d \cdot \sum\limits_{i = 1}^{\frac{n}{d}}\sum\limits_{j = 1}^{\frac{n}{d}} [\gcd(i,j) = 1] \]

\(g(n) = \sum\limits_{i = 1}^n\sum\limits_{j = 1}^n [\gcd(i,j) = 1]\),则式子化为:

\[\sum\limits_{d = 1} ^ n d \cdot g(\frac{n}{d}) \]

考虑化简 \(g(n)\),注意到:

\[\varphi(n) = \sum\limits_{i = 1}^n [\gcd(n, i) = 1] \]

则有:

\[g(n) = 2 \cdot \sum\limits_{i = 1}^n \varphi(i) - 1 \]

线性筛 \(\mathcal{O(n)}\) 预处理出欧拉函数,再求一遍欧拉函数前缀和,即可 \(\mathcal{O(1)}\) 计算 \(g(n)\)

至此 \(\sum\limits_{d = 1} ^ n d \cdot g(\frac{n}{d})\) 已经可以 \(\mathcal{O(n)}\) 计算,可以进一步用 " 数论分块 " 优化到 \(O(\sqrt n)\)

\[\texttt{Code} \]

#include 

using namespace std;

const int N = 2000100;

int n;

int m, prime[N], fac[N];
int phi[N];
long long S[N];

void GetPrimes(int N) {
	phi[1] = 1;
	for (int i = 2; i <= N; i ++) {
		if (!fac[i]) fac[i] = i, prime[++ m] = i, phi[i] = i - 1;
		for (int j = 1; j <= m; j ++) {
			if (prime[j] > fac[i] || prime[j] > N / i) break;
			fac[i * prime[j]] = prime[j];
			phi[i * prime[j]] = phi[i] * (i % prime[j] ? prime[j] - 1 : prime[j]);
		}
	}

	for (int i = 1; i <= N; i ++)
		S[i] = S[i - 1] + phi[i];
}

long long g(int n) {
	return 2 * S[n] - 1;
}

int main() {
	GetPrimes(2000000);

	scanf("%d", &n);

	long long ans = 0;
	for (int x = 1, Nx; x <= n; x = Nx + 1) {
		Nx = n / (n / x);
		ans += 1ll * (x + Nx) * (Nx - x + 1) / 2 * g(n / x);
	}

	ans -= 1ll * n * (n + 1) / 2;
	ans /= 2;

	printf("%lld\n", ans);

	return 0;
}

\[\texttt{Thanks} \ \texttt{for} \ \texttt{reading} \]

你可能感兴趣的:(Luogu P1390 公约数的和)