[莫反] P1829 Crash的数字表格

posted on 2024-03-09 05:21:06 | under | source

前言:自己推的,和部分题解(包括当前第一篇)不太一样。

为了方便令 \(n\le m\),下文的除号表示向下取整,并且和式都默认从 \(1\) 开始枚举。

问题是求 \(\sum\limits_i^n\sum\limits_j^mlcm(i,j)\)

转成熟悉的公因数形式:

\(\sum\limits_i^n\sum\limits_j^m\frac {ij}{gcd(i,j)}\)

枚举公因数,并将 \(i,j\) 同时除以 \(d\)

\(\sum\limits_d^n\frac1d\sum\limits_i^{\frac nd}\sum\limits_j^{\frac md}id\times jd [gcd(i,j)==1]\)

\(\sum\limits_d^nd\sum\limits_i^{\frac nd}\sum\limits_j^{\frac md}ij [gcd(i,j)==1]\)

莫反,这里跳了一步:

\(\sum\limits_d^nd\sum\limits_i^{\frac nd}\sum\limits_j^{\frac md}ij\sum\limits_{p\mid i,p\mid j} \mu(p)\)

将后半部分的 \(\mu\) 提上来,并将 \(i,j\) 同时除以 \(p\)

\(\sum\limits_d^nd\sum\limits_p^n\mu(p)\sum\limits_i^{\frac n{dp}}\sum\limits_j^{\frac m{dp}}ip\times jp\)

把能提出来变量的都提:

\(\sum\limits_d^nd\sum\limits_p^np^2\mu(p)\sum\limits_i^{\frac n{dp}}i\sum\limits_j^{\frac m{dp}}j\)

\(G(n)=\sum\limits_{i}^n i\),化简原式:

\(\sum\limits_d^nd\sum\limits_p^np^2\mu(p)G(\frac n{dp})G(\frac m{dp})\)

枚举 \(dp=T\)

\(\sum\limits_T^n G(\frac nT)G(\frac mT) \sum\limits_{d\mid T} d^2\mu(d)\frac Td\)

最终式子长这样:

\(\sum\limits_T^n G(\frac nT)G(\frac mT) \sum\limits_{d\mid T} dT\mu(d)\)

后半部分的和式显然是积性函数,线性筛预处理前缀和,然后整除分块即可。复杂度 \(O(n+\sqrt n)\)

#include<bits/stdc++.h>
using namespace std;

#define int long long
const int N = 1e7 + 5, mod = 20101009;
int T, n, m, k, ans;
int mi[N], f[N], ts[N], mu[N], prime[N], pc, tot;
bool flag[N];

inline int qstp(int a, int k) {int res = 1; for(; k; k >>= 1, a = a * a % mod) if(k & 1) res = res * a % mod; return res;}
inline void init(){
	f[1] = 1, flag[1] = 1, mu[1] = 1;
	for(int i = 2; i < N; ++i){
		if(!flag[i]) prime[++pc] = i, mi[i] = i, ts[i] = i, mu[i] = -1, f[i] = (i * (1 + mu[i] * i) + mod) % mod;
		for(int j = 1; j <= pc && i * prime[j] < N; ++j){
			int q = i * prime[j];
			flag[q] = 1, mi[q] = prime[j], ts[q] = prime[j] * (mi[i] == prime[j] ? ts[i] : 1);
			mu[q] = i % prime[j] == 0 ? 0 : -mu[i];
			int A = ts[q], B = q / A;
			if(B == 1)
				f[q] = (q * (1 + mu[prime[j]] * prime[j]) % mod + mod) % mod;
			else
				f[q] = f[A] * f[B] % mod;
			if(i % prime[j] == 0) break; 
		} 
	}
	for(int i = 2; i < N; ++i) f[i] = (f[i] + f[i - 1]) % mod;
}
inline int G(int a) {return (a + 1) * a / 2 % mod;}
inline int getF(int a){
	int res = 0;
	for(int d = 1; d <= a; ++d){
		if(a % d) continue;
		res += mu[d] * d * a;
	}
	return ((res % mod) + mod) % mod;
}
signed main(){
	init();
	cin >> n >> m;
	if(n > m) swap(n, m);
	for(int l = 1; l <= n;){
		int r = min(n / (n / l), m / (m / l));
		ans = (ans + G(n / l) * G(m / l) % mod * ((f[r] - f[l - 1]) % mod + mod) % mod) % mod;
		l = r + 1;
	}
	cout << ans;
	return 0;
}
posted @ 2026-01-12 20:17  Zwi  阅读(3)  评论(0)    收藏  举报