Loading

题解-[国家集训队]Crash的数字表格 / JZPTAB

题解-[国家集训队]Crash的数字表格 / JZPTAB

前置知识:

莫比乌斯反演 </>


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

单组测试数据,给定 \(n,m\) ,求

\[\sum\limits_{i=1}^n\sum\limits_{j=1}^m\operatorname{lcm}(i,j)\bmod 20101009 \]

数据范围:\(1\le n,m\le 10^7\)


作为写出了最暴力的做法的蒟蒻,来推个式子。

\(n\le m\),一气呵成:

\[\begin{split} g(n,m)=&\sum\limits_{i=1}^n\sum\limits_{j=1}^m\operatorname{lcm}(i,j)\\ =&\sum\limits_{i=1}^n\sum\limits_{j=1}^m\frac{ij}{\gcd(i,j)}\\ =&\sum\limits_{d=1}^n\sum\limits_{i=1}^n\sum\limits_{j=1}^m\frac{ij}{d}[\gcd(i,j)=d]\\ =&\sum\limits_{d=1}^n\sum\limits_{i=1}^{\lfloor\frac nd\rfloor}\sum\limits_{j=1}^{\lfloor\frac md\rfloor}ijd[\gcd(i,j)=1]\\ =&\sum\limits_{d=1}^n d\sum\limits_{i=1}^{\lfloor\frac nd\rfloor}i\sum\limits_{j=1}^{\lfloor\frac md\rfloor}j\sum\limits_{k|\gcd(i,j)}\mu(k)\\ =&\sum\limits_{d=1}^n d\sum\limits_{k=1}^n\mu(k)\sum\limits_{i=1}^{\lfloor\frac nd\rfloor}i[k|i]\sum\limits_{j=1}^{\lfloor\frac md\rfloor}j[k|j]\\ =&\sum\limits_{d=1}^n d\sum\limits_{k=1}^n\mu(k)\sum\limits_{i=1}^{\lfloor\frac {n}{dk}\rfloor}ik\sum\limits_{j=1}^{\lfloor\frac {m}{dk}\rfloor}jk\\ =&\sum\limits_{d=1}^n d\sum\limits_{k=1}^nk^2\mu(k)\frac{\lfloor\frac{n}{dk}\rfloor(\lfloor\frac{n}{dk}\rfloor+1)}{2}\cdot\frac{\lfloor\frac{m}{dk}\rfloor(\lfloor\frac{m}{dk}\rfloor+1)}{2}\\ \end{split} \]

\(x=dk\) 带入:

\[g(n,m)=\sum\limits_{x=1}^nx\cdot\frac{\lfloor\frac{n}{x}\rfloor(\lfloor\frac{n}{x}\rfloor+1)}{2}\cdot\frac{\lfloor\frac{m}{x}\rfloor(\lfloor\frac{m}{x}\rfloor+1)}{2}\sum\limits_{k|x}k\mu(k) \]

然后筛 \(\mu(k)\) 时顺便计算 \(h(k)=k\mu(k)\),最后狄利克雷前缀和求 \(f(k)=\sum\limits_{k|x}k\mu(k)\)

别忘了膜拜 \(20101009\),时间复杂度 \(\Theta(N+n)\)

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

//&Start
#define lng long long
#define lit long double
#define kk(i,n) "\n "[i<n]
const int inf=0x3f3f3f3f;
const lng Inf=1e17;

//&Mobius
const int N=1e7;
const int mod=20101009;
bitset<N+10> np;
int mu[N+10],cnt,p[N+10],f[N+10];
void Mobius(){
	f[1]=mu[1]=1;
	for(int i=2;i<=N;i++){
		if(!np[i]) p[++cnt]=i,mu[i]=-1;
		f[i]=(mu[i]*i+mod)%mod;
		for(int j=1;j<=cnt&&i*p[j]<=N;j++){
			np[i*p[j]]=1;
			if(i%p[j]==0){mu[i*p[j]]=0;break;}
			mu[i*p[j]]=-mu[i];
		}
	}
	for(int j=1;j<=cnt;j++)
		for(int i=1;i*p[j]<=N;i++)
			(f[i*p[j]]+=f[i])%=mod; //狄利克雷前缀和
}


//&Data
int n,m,ans;
int bitfun(int x){
	lng res=1ll*x*f[x]%mod;
	(res*=1ll*(n/x+1)*(n/x)/2%mod)%=mod;
	(res*=1ll*(m/x+1)*(m/x)/2%mod)%=mod; //如上
	//这个1ll不乘要爆long long,30分。
	return (int)res;
}

//&Main
int main(){
	Mobius();
	scanf("%d%d",&n,&m);
	if(n>m) swap(n,m);
	for(int i=1;i<=n;i++)
		(ans+=bitfun(i))%=mod;
	printf("%d\n",ans);
	return 0;
}

祝大家学习愉快!

posted @ 2020-03-10 17:18  George1123  阅读(151)  评论(0编辑  收藏  举报