洛谷P1829 [国家集训队]Crash的数字表格 / JZPTAB

洛谷P1829 [国家集训队]Crash的数字表格 / JZPTAB

题目大意

给出 n , m n,m n,m,求 ∑ i = 1 n ∑ j = 1 m l c m ( i , j ) \sum\limits_{i=1}^n\sum\limits_{j=1}^m lcm(i,j) i=1nj=1mlcm(i,j)

题解

前置知识:莫比乌斯反演

不妨设 n ≤ m n\leq m nm

题意即求

∑ i = 1 n ∑ j = 1 m i × j gcd ⁡ ( i , j ) \sum\limits_{i=1}^n\sum\limits_{j=1}^m \dfrac{i\times j}{\gcd(i,j)} i=1nj=1mgcd(i,j)i×j

枚举 gcd ⁡ \gcd gcd

∑ d = 1 n ∑ i = 1 n ∑ j = 1 m i × j d [ gcd ⁡ ( i , j ) = d ] \sum\limits_{d=1}^n\sum\limits_{i=1}^n\sum\limits_{j=1}^m\dfrac{i\times j}{d}[\gcd(i,j)=d] d=1ni=1nj=1mdi×j[gcd(i,j)=d]

稍作转换可得

∑ d = 1 n d ∑ i = 1 ⌊ n d ⌋ ∑ j = 1 ⌊ m d ⌋ i × j × [ gcd ⁡ ( i , j ) = 1 ] \sum\limits_{d=1}^nd\sum\limits_{i=1}^{\lfloor\frac nd\rfloor}\sum\limits_{j=1}^{\lfloor\frac md\rfloor}i\times j\times[\gcd(i,j)=1] d=1ndi=1dnj=1dmi×j×[gcd(i,j)=1]

利用莫比乌斯函数的性质,可得

∑ d = 1 n d ∑ i = 1 ⌊ n d ⌋ ∑ j = 1 ⌊ m d ⌋ i × j ∑ k ∣ gcd ⁡ ( i , j ) μ ( t ) \sum\limits_{d=1}^nd\sum\limits_{i=1}^{\lfloor\frac nd\rfloor}\sum\limits_{j=1}^{\lfloor\frac md\rfloor}i\times j\sum\limits_{k|\gcd(i,j)}\mu(t) d=1ndi=1dnj=1dmi×jkgcd(i,j)μ(t)

枚举 k k k

∑ d = 1 n d ∑ k = 1 ⌊ n d ⌋ k 2 × μ ( k ) ∑ i = 1 ⌊ n k d ⌋ ∑ j = 1 ⌊ m k d ⌋ i × j \sum\limits_{d=1}^nd\sum\limits_{k=1}^{\lfloor\frac nd\rfloor}k^2\times \mu(k)\sum\limits_{i=1}^{\lfloor\frac{n}{kd}\rfloor}\sum\limits_{j=1}^{\lfloor\frac{m}{kd}\rfloor}i\times j d=1ndk=1dnk2×μ(k)i=1kdnj=1kdmi×j

∑ i = 1 ⌊ n k d ⌋ ∑ j = 1 ⌊ m k d ⌋ i × j \sum\limits_{i=1}^{\lfloor\frac{n}{kd}\rfloor}\sum\limits_{j=1}^{\lfloor\frac{m}{kd}\rfloor}i\times j i=1kdnj=1kdmi×j可变为 ⌊ n k d ⌋ × ( ⌊ n k d ⌋ + 1 ) 2 × ⌊ n k d ⌋ × ( ⌊ n k d ⌋ + 1 ) 2 \dfrac{\lfloor\frac{n}{kd}\rfloor\times(\lfloor\frac{n}{kd}\rfloor+1)}{2}\times \dfrac{\lfloor\frac{n}{kd}\rfloor\times (\lfloor\frac{n}{kd}\rfloor+1)}{2} 2kdn×(⌊kdn+1)×2kdn×(⌊kdn+1)。设 g t ( k ) = k × ( k + 1 ) 2 gt(k)=\dfrac{k\times (k+1)}{2} gt(k)=2k×(k+1),则原式变为

∑ d = 1 n d ∑ k = 1 ⌊ n d ⌋ k 2 × μ ( k ) × g t ( ⌊ n k d ⌋ ) × g t ( ⌊ m k d ⌋ ) \sum\limits_{d=1}^nd\sum\limits_{k=1}^{\lfloor\frac nd\rfloor}k^2\times \mu(k)\times gt(\lfloor\dfrac{n}{kd}\rfloor)\times gt(\lfloor\dfrac{m}{kd}\rfloor) d=1ndk=1dnk2×μ(k)×gt(⌊kdn⌋)×gt(⌊kdm⌋)

s u m ( n , m ) = ∑ k = 1 n k 2 μ ( k ) × g t ( ⌊ n k ⌋ ) × g t ( ⌊ m k ⌋ ) sum(n,m)=\sum\limits_{k=1}^nk^2\mu(k)\times gt(\lfloor\dfrac nk\rfloor)\times gt(\lfloor\dfrac mk\rfloor) sum(n,m)=k=1nk2μ(k)×gt(⌊kn⌋)×gt(⌊km⌋),则 s u m ( n , m ) sum(n,m) sum(n,m)用数论分块可以 O ( n ) O(\sqrt n) O(n )求出。

则原式变为

∑ d = 1 n d × s u m ( ⌊ n d ⌋ , ⌊ m d ⌋ ) \sum\limits_{d=1}^nd\times sum(\lfloor\dfrac nd\rfloor,\lfloor\dfrac md\rfloor) d=1nd×sum(⌊dn,dm⌋)

我们发现这里也可以数论分块。两个数论分块套起来,总时间复杂度为 O ( n ) O(n) O(n)

code

#include
using namespace std;
const long long mod=20101009;
int n,m,z[10000005],p[10000005],mu[10000005];
long long s[10000005];
long long ans=0;
long long gt(int t){
	return 1ll*t*(t+1)/2%mod;
}
long long sum(int v1,int v2){
	long long re=0;
	for(int l=1,r;l<=v1;l=r+1){
		r=min(v1/(v1/l),v2/(v2/l));
		re=(re+(s[r]-s[l-1]+mod)%mod*gt(v1/l)%mod*gt(v2/l)%mod)%mod;
	}
	return re;
}
int main()
{
	scanf("%d%d",&n,&m);
	if(n>m) swap(n,m);
	mu[1]=1;
	for(int i=2;i<=n;i++){
		if(!z[i]){
			p[++p[0]]=i;mu[i]=-1;
		}
		for(int j=1;j<=p[0]&&i*p[j]<=n;j++){
			z[i*p[j]]=1;
			if(i%p[j]==0){
				mu[i*p[j]]=0;
				break;
			}
			mu[i*p[j]]=-mu[i];
		}
	}
	for(int i=1;i<=n;i++){
		s[i]=(s[i-1]+1ll*(mu[i]+mod)%mod*i%mod*i%mod)%mod;
	}
	for(int l=1,r;l<=n;l=r+1){
		r=min(n/(n/l),m/(m/l));
		ans=(ans+1ll*(r-l+1)*(r+l)/2%mod*sum(n/l,m/l)%mod)%mod;
	}
	printf("%lld",ans);
	return 0;
}

加强版

本题有加强版,有多组数据。

洛谷P1829 [国家集训队]Crash的数字表格 / JZPTAB(包括多组数据)

你可能感兴趣的:(题解,c++)