【莫比乌斯反演】BZOJ2154[Crash的数字表格]题解

题目概述

∑ i = 1 n ∑ j = 1 m l c m ( i , j ) \sum_{i=1}^{n}\sum_{j=1}^{m}lcm(i,j) i=1nj=1mlcm(i,j)

解题报告

第一道反演题……首先先要知道 e = μ ∗ 1 e=\mu*1 e=μ1证明戳这里

莫比乌斯反演: f = g ∗ 1 ⇔ g = f ∗ μ f=g*1\Leftrightarrow g=f*\mu f=g1g=fμ ,证明:
f = g ∗ 1 ⇔ g ∗ ( μ ∗ 1 ) = f ∗ μ ⇔ g ∗ e = f ∗ μ ⇔ g = f ∗ μ f=g*1\Leftrightarrow g*(\mu*1)=f*\mu\Leftrightarrow g*e=f*\mu\Leftrightarrow g=f*\mu f=g1g(μ1)=fμge=fμg=fμ
也就是说若 F ( n ) = ∑ d ∣ n f ( d ) F(n)=\sum_{d|n}f(d) F(n)=dnf(d) ,则 f ( n ) = ∑ d ∣ n F ( d ) μ ( n d ) f(n)=\sum_{d|n}F(d)\mu({n\over d}) f(n)=dnF(d)μ(dn)


这道题先列出答案式子:
∑ i = 1 n ∑ j = 1 m [ i , j ] = ∑ i = 1 n ∑ j = 1 m i j g c d ( i , j ) \sum_{i=1}^{n}\sum_{j=1}^{m}[i,j]=\sum_{i=1}^{n}\sum_{j=1}^{m}{ij\over gcd(i,j)} i=1nj=1m[i,j]=i=1nj=1mgcd(i,j)ij
f ( n ) = 1 n , f ( n ) = ∑ d ∣ n F ( d ) f(n)={1\over n},f(n)=\sum_{d|n}F(d) f(n)=n1,f(n)=dnF(d) ,则:
= ∑ i = 1 n ∑ j = 1 m i j × f [ g c d ( i , j ) ] = ∑ i = 1 n ∑ j = 1 m i j ∑ d ∣ i , d ∣ j F ( d ) = ∑ d = 1 m i n ( n , m ) F ( d ) ∑ i = 1 n ∑ j = 1 m i j [ d ∣ i , d ∣ j ] = ∑ d = 1 m i n ( n , m ) F ( d ) d 2 ∑ i = 1 ⌊ n d ⌋ ∑ j = 1 ⌊ m d ⌋ i j =\sum_{i=1}^{n}\sum_{j=1}^{m}ij\times f[gcd(i,j)]=\sum_{i=1}^{n}\sum_{j=1}^{m}ij\sum_{d|i,d|j}F(d)\\ =\sum_{d=1}^{min(n,m)}F(d)\sum_{i=1}^{n}\sum_{j=1}^{m}ij[d|i,d|j]=\sum_{d=1}^{min(n,m)}F(d)d^2\sum_{i=1}^{\lfloor{n\over d}\rfloor}\sum_{j=1}^{\lfloor{m\over d}\rfloor}ij =i=1nj=1mij×f[gcd(i,j)]=i=1nj=1mijdi,djF(d)=d=1min(n,m)F(d)i=1nj=1mij[di,dj]=d=1min(n,m)F(d)d2i=1dnj=1dmij
后面的 ∑ i = 1 ⌊ n d ⌋ i ∑ j = 1 ⌊ m d ⌋ j \sum_{i=1}^{\lfloor{n\over d}\rfloor}i\sum_{j=1}^{\lfloor{m\over d}\rfloor}j i=1dnij=1dmj 就是两个等差数列前 x x x 项和的乘积,我们记为 S ( d ) S(d) S(d) ,接下来就用到了反演:
= ∑ d = 1 m i n ( n , m ) F ( d ) d 2 S ( d ) = ∑ d = 1 m i n ( n , m ) S ( d ) ∑ k ∣ d f ( d k ) μ ( k ) d 2 = ∑ d = 1 m i n ( n , m ) S ( d ) ∑ k ∣ d k d × d 2 μ ( k ) = ∑ d = 1 m i n ( n , m ) S ( d ) ∑ k ∣ d μ ( k ) k d =\sum_{d=1}^{min(n,m)}F(d)d^2S(d)=\sum_{d=1}^{min(n,m)}S(d)\sum_{k|d}f({d\over k})\mu(k)d^2\\ =\sum_{d=1}^{min(n,m)}S(d)\sum_{k|d}{k\over d}\times d^2\mu(k)=\sum_{d=1}^{min(n,m)}S(d)\sum_{k|d}\mu(k)kd =d=1min(n,m)F(d)d2S(d)=d=1min(n,m)S(d)kdf(kd)μ(k)d2=d=1min(n,m)S(d)kddk×d2μ(k)=d=1min(n,m)S(d)kdμ(k)kd
我们会发现后面的 H ( d ) = ∑ k ∣ d μ ( k ) k d H(d)=\sum_{k|d}\mu(k)kd H(d)=kdμ(k)kd 是积性函数,所以可以用线性筛:
H ( p ) = p − p 2 H ( a p ) = H ( a ) H ( p ) , g c d ( a , p ) = 1 H ( a p ) = H ( a ) p , g c d ( a , p ) = p H(p)=p-p^2\\ H(ap)=H(a)H(p),gcd(a,p)=1\\ H(ap)=H(a)p,gcd(a,p)=p H(p)=pp2H(ap)=H(a)H(p),gcd(a,p)=1H(ap)=H(a)p,gcd(a,p)=p

简单证明: g c d ( a , p ) = p gcd(a,p)=p gcd(a,p)=p 时, H ( a p ) H(ap) H(ap) H ( a ) H(a) H(a) 多出的 k k k 一定含有 p 2 p^2 p2 而使 μ ( k ) = 0 \mu(k)=0 μ(k)=0 ,相同 k k k × p \times p ×p ,所以 H ( a p ) = H ( a ) p H(ap)=H(a)p H(ap)=H(a)p

那么答案就是 ∑ i = 1 m i n ( n , m ) S ( d ) H ( d ) \sum_{i=1}^{min(n,m)}S(d)H(d) i=1min(n,m)S(d)H(d) ,其实可以分块加快速度,不过我太懒就没写:P。

示例程序

#include<cstdio>
using namespace std;
typedef long long LL;
const int maxn=1e7,MOD=20101009;

int n,m,H[maxn+5],ans;
int p[maxn+5];bool pri[maxn+5];

inline void AMOD(int &x,int tem) {if ((x+=tem)>=MOD) x-=MOD;}
void Make(int n)
{
	pri[1]=true;H[1]=1;
	for (int i=2;i<=n;i++)
	{
		if (!pri[i]) p[++p[0]]=i,AMOD(H[i]=i,MOD-(LL)i*i%MOD);
		for (int j=1,t;j<=p[0]&&(t=i*p[j])<=n;j++)
		{
			pri[t]=true;H[t]=(LL)H[i]*H[p[j]]%MOD;
			if (!(i%p[j])) {H[t]=(LL)H[i]*p[j]%MOD;continue;}
		}
	}
}
inline LL S(int d) {LL A=n/d,B=m/d;return ((A+1)*A/2)%MOD*((B+1)*B/2%MOD)%MOD;}
int main()
{
	freopen("program.in","r",stdin);
	freopen("program.out","w",stdout);
	scanf("%d%d",&n,&m);Make(n);
	for (int i=1;i<=n&&i<=m;i++) AMOD(ans,S(i)*H[i]%MOD);
	return printf("%d\n",ans),0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值