转载自An_Account大佬

提示:别用莫比乌斯反演公式,会炸的

只需要记住:

[gcd(i,j)=1]=∑d∣gcd(i,j)μ(d)[gcd(i,j)=1]=\sum_{d|gcd(i,j)}\mu(d)[gcd(i,j)=1]=d∣gcd(i,j)∑?μ(d)

证明?其实很简单。

μ\muμ函数有个性质

∑d∣nμ(d)=[d=1]\sum_{d|n}\mu(d)=[d=1]d∣n∑?μ(d)=[d=1]

将ddd替换成gcd(i,j)gcd(i,j)gcd(i,j)就是上面的那个暂且可以称作公式的式子了

例1

求∑i=1n∑j=1m[gcd(i,j)=1] (n<m)\sum_{i=1}{n}\sum_{j=1}{m}[gcd(i,j)=1]\ \ \ \ (n<m)i=1∑n?j=1∑m?[gcd(i,j)=1] (n<m)

直接套公式啦

=∑i=1n∑j=1m∑d∣gcd(i,j)μ(d)=\sum_{i=1}{n}\sum_{j=1}{m}\sum_{d|gcd(i,j)}\mu(d)=i=1∑n?j=1∑m?d∣gcd(i,j)∑?μ(d)

然后我们枚举ddd,显然有d∈(1,n) (d∣gcd(i,j))d\in(1,n)\ \ \ (d|gcd(i,j))d∈(1,n) (d∣gcd(i,j))

于是将ddd提到前面去,则i,ji,ji,j都是ddd的倍数,化简一下,得

=∑d=1nμ(d)??nd???md?=\sum_{d=1}^{n}\mu(d)\lfloor\frac{n}{d}\rfloor\lfloor\frac{m}{d}\rfloor=d=1∑n?μ(d)??d

n????d

m??

注意到后面那一坨是可以O(n)O(\sqrt n)O(n

?)分块做的

于是我们实现了O(n2)O(n^2)O(n2)到O(n)O(\sqrt n)O(n

?)的过渡

简单吧

例2

∑i=1n∑j=1m[gcd(i,j)=k] (n<m)\sum_{i=1}{n}\sum_{j=1}{m}[gcd(i,j)=k]\ \ \ \ (n<m)i=1∑n?j=1∑m?[gcd(i,j)=k] (n<m)

好像与上一题有点不一样

但我们可以转化成一样的

同时除以kkk,得

=∑i=1?nk?∑j=1?mk?[gcd(i,j)=1]=\sum_{i=1}{\lfloor\frac{n}{k}\rfloor}\sum_{j=1}{\lfloor\frac{m}{k}\rfloor}[gcd(i,j)=1]=i=1∑?k

n???j=1∑?k

m???[gcd(i,j)=1]

然后就一样了

例3

∑i=1n∑j=1mij[gcd(i,j)=k] (n<m)\sum_{i=1}{n}\sum_{j=1}{m}ij[gcd(i,j)=k]\ \ \ \ (n<m)i=1∑n?j=1∑m?ij[gcd(i,j)=k] (n<m)

老方法,同时除以kkk,只不过与上一题不同的是,我们需要考虑i,ji,ji,j的贡献

=∑i=1?nk?∑j=1?mk?ij[gcd(i,j)=1]?k2=\sum_{i=1}{\lfloor\frac{n}{k}\rfloor}\sum_{j=1}{\lfloor\frac{m}{k}\rfloor}ij[gcd(i,j)=1]*k^2=i=1∑?k

n???j=1∑?k

m???ij[gcd(i,j)=1]?k2

有同学可能要问了

为什么最后要乘以一个k2k^2k2啊?

因为在i,ji,ji,j同时除以kkk的同时,中间那个ijijij的值就变了,i,ji,ji,j同时缩小到了原来的1k\frac{1}{k}k

1?,所以最后要把缩小的乘回来,就是k2k^2k2

让我们继续套路,将中间那个gcd(i,j)gcd(i,j)gcd(i,j)用莫比乌斯替换掉

=∑i=1?nk?∑j=1?mk?ij∑d∣gcd(i,j)μ(d)?k2=\sum_{i=1}{\lfloor\frac{n}{k}\rfloor}\sum_{j=1}{\lfloor\frac{m}{k}\rfloor}ij\sum_{d|gcd(i,j)}\mu(d)*k^2=i=1∑?k

n???j=1∑?k

m???ijd∣gcd(i,j)∑?μ(d)?k2

提出ddd,同样,在最后乘以一个d2d^2d2

=∑d=1?nk?μ(d)?d2∑i=1?nkd?∑j=1?mkd?ij?k2=\sum_{d=1}{\lfloor\frac{n}{k}\rfloor}\mu(d)*d2\sum_{i=1}{\lfloor\frac{n}{kd}\rfloor}\sum_{j=1}{\lfloor\frac{m}{kd}\rfloor}ij*k^2=d=1∑?k

n???μ(d)?d2i=1∑?kd

n???j=1∑?kd

m???ij?k2

各归各家,各找各妈

=k2?∑d=1?nk?μ(d)?d2∑i=1?nkd?i∑j=1?mkd?j=k2*\sum_{d=1}{\lfloor\frac{n}{k}\rfloor}\mu(d)*d2\sum_{i=1}{\lfloor\frac{n}{kd}\rfloor}i\sum_{j=1}^{\lfloor\frac{m}{kd}\rfloor}j=k2?d=1∑?k

n???μ(d)?d2i=1∑?kd

n???ij=1∑?kd

m???j

我们发现,最后那两项,不就是…\dots…等差数列吗?

时间复杂度O(n2)→O(n)O(n^2)\rightarrow O(\sqrt n)O(n2)→O(n

?)

来一个强的

例4

求∑i=1n∑j=1mlcm(i,j)\sum_{i=1}{n}\sum_{j=1}{m}lcm(i,j)i=1∑n?j=1∑m?lcm(i,j)

首先,小学奥数告诉我们

lcm(i,j)=i?jgcd(i,j)lcm(i,j)=\frac{i*j}{gcd(i,j)}lcm(i,j)=gcd(i,j)

i?j?

可以看看我的另外一篇博客莫比乌斯反演-从莫比乌斯到欧拉,里面详细地介绍了一种奇妙的反演方法,大致思路是用?\phi?函数替换μ\muμ函数。我暂且把它叫做欧拉反演。

但是注意,如果gcd(i,j)gcd(i,j)gcd(i,j)出现在分母这种不正常的位置,就不能用那个神奇的欧拉反演,而应该用常规方法。

先科普一下:积性函数,稍后会有用的

仍然是老套路,枚举gcd(i,j)gcd(i,j)gcd(i,j)

=∑d=1n∑i=1n∑j=1mi?jd?[gcd(i,j)=d]=\sum_{d=1}{n}\sum_{i=1}{n}\sum_{j=1}^{m}\frac{ij}{d}[gcd(i,j)=d]=d=1∑n?i=1∑n?j=1∑m?d

i?j??[gcd(i,j)=d]

同时除以ddd

=∑d=1n∑i=1?nd?∑j=1?md?i?j?d?[gcd(i,j)=1]=\sum_{d=1}{n}\sum_{i=1}{\lfloor\frac{n}{d}\rfloor}\sum_{j=1}^{\lfloor\frac{m}{d}\rfloor}ijd*[gcd(i,j)=1]=d=1∑n?i=1∑?d

n???j=1∑?d

m???i?j?d?[gcd(i,j)=1]

=∑d=1n∑i=1?nd?∑j=1?md?i?j?d∑k∣gcd(i,j)μ(k)=\sum_{d=1}{n}\sum_{i=1}{\lfloor\frac{n}{d}\rfloor}\sum_{j=1}^{\lfloor\frac{m}{d}\rfloor}ijd\sum_{k|gcd(i,j)}\mu(k)=d=1∑n?i=1∑?d

n???j=1∑?d

m???i?j?dk∣gcd(i,j)∑?μ(k)

枚举kkk

=∑d=1nd∑k=1?nd?μ(k)?k2∑i=1?ndk?i∑j=1?mdk?j=\sum_{d=1}{n}d\sum_{k=1}{\lfloor\frac{n}{d}\rfloor}\mu(k)*k2\sum_{i=1}{\lfloor\frac{n}{dk}\rfloor}i\sum_{j=1}^{\lfloor\frac{m}{dk}\rfloor}j=d=1∑n?dk=1∑?d

n???μ(k)?k2i=1∑?dk

n???ij=1∑?dk

m???j

这时,这已经是一个O(n)O(n)O(n)的做法,观察可以得到,?nd?\lfloor\frac{n}{d}\rfloor?d

n??可以分一次块,?ndk?\lfloor\frac{n}{dk}\rfloor?dk

n??可以再分一次块,总时间复杂度是O(n?n)=O(n)O(\sqrt n*\sqrt n)=O(n)O(n

??n

?)=O(n)

推到这里已经很牛逼了,但我们还有更好的方法,这个时间复杂度还能优化

后面那两坨等差数列很烦,我们把它换掉

设T=dk,f(x)=∑i=1xiT=dk,f(x)=\sum_{i=1}^{x}iT=dk,f(x)=∑i=1x?i,把原来那个式子换成

=∑d=1nd∑k=1?nd?μ(k)?k2?f(?nT?)?f(?mT?)=\sum_{d=1}{n}d\sum_{k=1}{\lfloor\frac{n}{d}\rfloor}\mu(k)k^2f(\lfloor\frac{n}{T}\rfloor)*f(\lfloor\frac{m}{T}\rfloor)=d=1∑n?dk=1∑?d

n???μ(k)?k2?f(?T

n??)?f(?T

m??)

看好了,下面的步骤很奇妙

用枚举gcd(i,j)gcd(i,j)gcd(i,j)的方法,我们枚举TTT

=∑T=1nf(?nT?)?f(?mT?)∑d∣Td?μ(Td)?(Td)2=\sum_{T=1}{n}f(\lfloor\frac{n}{T}\rfloor)*f(\lfloor\frac{m}{T}\rfloor)\sum_{d|T}d*\mu(\frac{T}{d})*(\frac{T}{d})2=T=1∑n?f(?T

n??)?f(?T

m??)d∣T∑?d?μ(d

T?)?(d

T?)2

=∑T=1nf(?nT?)?f(?mT?)∑d∣Td?μ(d)?T=\sum_{T=1}^{n}f(\lfloor\frac{n}{T}\rfloor)f(\lfloor\frac{m}{T}\rfloor)\sum_{d|T}d\mu(d)*T=T=1∑n?f(?T

n??)?f(?T

m??)d∣T∑?d?μ(d)?T

em…\dots…貌似没法用狄利克雷卷积

但别担心,我们观察最后这个式子

∑d∣Td?μ(d)?T\sum_{d|T}d\mu(d)Td∣T∑?d?μ(d)?T

先不管TTT

∑d∣Td?μ(d)\sum_{d|T}d*\mu(d)d∣T∑?d?μ(d)

设F(T)=∑d∣Td?μ(d)F(T)=\sum_{d|T}d*\mu(d)F(T)=d∣T∑?d?μ(d)

我们考虑a⊥ba\perp ba⊥b

F(a)=∑d∣ad?μ(d)F(a)=\sum_{d|a}d*\mu(d)F(a)=d∣a∑?d?μ(d)

F(b)=∑d∣bd?μ(d)F(b)=\sum_{d|b}d*\mu(d)F(b)=d∣b∑?d?μ(d)

显然a,ba,ba,b对F(ab)F(ab)F(ab)的贡献是没有交集的,而这时,在我们枚举ddd时,它既可以是aaa的约数,也可以是bbb的约数,还能是ababab的约数。具体来说,F(a)F(a)F(a)的某一项乘F(b)F(b)F(b)的某一项一定等于F(ab)F(ab)F(ab)的某一项(一个aaa的因子与一个bbb的因子相乘一定是ababab的因子)

又因为a⊥ba\perp ba⊥b,故有

μ(a\mu(aμ(a的某个因子k)?μ(bk)\mu(bk)?μ(b的某个因子j)=μ(k?j)j)=\mu(kj)j)=μ(k?j)

所以,FFF不就是一个积性函数吗?

常识告诉我们,积性函数是可以O(n)O(n)O(n)筛的,FFF也一样

F(1)=1F(1)=1F(1)=1

如果aaa是质数,则

F(a)=1?aF(a)=1-aF(a)=1?a 如果a⊥ba\perp ba⊥b,则

F(a?b)=F(a)?F(b)F(ab)=F(a)F(b)F(a?b)=F(a)?F(b)

这三个公式易得出,我们考虑a≡0 (mod b)a\equiv 0\ (mod\ b)a≡0 (mod b)且bbb是质数的情况

则F(a?b)F(a*b)F(a?b)比F(a)F(a)F(a)多出的几项中,ddd分解后,项bbb的次数一定大于111

想一想,为什么

因为,如果bbb这一项的次数小于等于111,它就一定在F(a)F(a)F(a)中被运算过了!(aaa一定有bbb这个质因子)

别忘了,当某个数的某个质因子次数大于111,它的μ\muμ值就是000啊!

故此时

F(a?b)=F(a)F(a*b)=F(a)F(a?b)=F(a)

于是,我们推导出了FFF函数的转移公式,代码表示如下(顺便处理一下前缀和)

void sieve() {

F[1]=sum[1]=1;

for (int i=2;i<=10000000;i++) {

if (!flag[i]) prime[++cnt]=i,F[i]=1-i;

for (int j=1;j<=cnt&&iprime[j]<=10000000;j++) {

flag[i
prime[j]]=1;

if (i%prime[j]==0) {//不互质

F[iprime[j]]=F[i];

break;

}

F[i
prime[j]]=F[i]F[prime[j]];//互质

}

sum[i]=sum[i-1]+F[i]
i;

}

}

回到公式

=∑T=1nf(?nT?)?f(?mT?)∑d∣Td?μ(d)?T=\sum_{T=1}^{n}f(\lfloor\frac{n}{T}\rfloor)f(\lfloor\frac{m}{T}\rfloor)\sum_{d|T}d\mu(d)*T=T=1∑n?f(?T

n??)?f(?T

m??)d∣T∑?d?μ(d)?T

仔细看代码,最后那个TTT已经在前缀和中处理了

我们只需要分块求前面那两个fff,后面那一坨O(1)O(1)O(1)处理(都筛出来了)

时间复杂度O(n)→O(n)O(n)\rightarrow O(\sqrt n)O(n)→O(n

?)

当你想降一下时间复杂度时,枚举第二个分块中的某一项再进行处理可能是一个好选择。

例5

∑i=1n∑j=1md(i?j)\sum_{i=1}{n}\sum_{j=1}{m}d(i*j)i=1∑n?j=1∑m?d(i?j)

其中,d(i?j)d(ij)d(i?j)表示i?jiji?j的约数个数

我们有一个公式

d(i?j)=∑x∣i∑y∣j[gcd(x,y)=1]d(i*j)=\sum_{x|i}\sum_{y|j}[gcd(x,y)=1]d(i?j)=x∣i∑?y∣j∑?[gcd(x,y)=1]

很多人不知道这个公式是怎么推的,我来解释一下

其实,这里的[gcd(i,j)=1][gcd(i,j)=1][gcd(i,j)=1]并不是为了去重,而是为了和左边的式子保持相等

我们考虑一个质数ppp,i=i′?pk1,j=j′?pk2i=i'*p{k_1},j=j'*p{k_2}i=i′?pk1?,j=j′?pk2?,注意这里k1,k2k_1,k_2k1?,k2?可以为000

考虑ppp对d(i?j)d(i*j)d(i?j)的贡献,显然,在ddd的因子中,ppp的这一项可以为000~k1+k2k_1+k_2k1?+k2?共k1+k2+1k_1+k_2+1k1?+k2?+1个

考虑等式右边,我们只看ppp这一项。x=x′?pkx,y=y′?pkyx=x'*p{k_x},y=y'*p{k_y}x=x′?pkx?,y=y′?pky?

要满足gcd(x,y)=1gcd(x,y)=1gcd(x,y)=1,那么就有gcd(pkx,pky)=1gcd(p{k_x},p{k_y})=1gcd(pkx?,pky?)=1

要么kx=0,ky∈[0,k2]k_x=0,k_y\in[0,k_2]kx?=0,ky?∈[0,k2?],共k2+1k_2+1k2?+1种

要么ky=0,kx∈[0,k1]k_y=0,k_x\in[0,k_1]ky?=0,kx?∈[0,k1?],共k1+1k_1+1k1?+1种

减去重复判断的kx=0,ky=0k_x=0,k_y=0kx?=0,ky?=0这种情况,最后答案k1+k2+1k_1+k_2+1k1?+k2?+1种

与等式左边相同!

剩下的步骤都很水了,所以我把这留作练习,如果你认真阅读了以上所有内容,那么这个练习就可以轻松解决。

练习

练习1

上面说了

练习2

∏i=1n∏j=1mf[gcd(i,j)] (n,m≤106,T≤1000)\prod_{i=1}{n}\prod_{j=1}{m}f[gcd(i,j)]\ \ \ (n,m\leq 10^6,T\leq 1000)i=1∏n?j=1∏m?f[gcd(i,j)] (n,m≤106,T≤1000)

fff是斐波那契数列

练习3

∑i=1n∑j=1mgcd(i,j)k (n,m≤5?106,T≤2000)\sum_{i=1}{n}\sum_{j=1}{m}gcd(i,j)^k\ \ \ (n,m\leq 5*10^6,T\leq 2000)i=1∑n?j=1∑m?gcd(i,j)k (n,m≤5?106,T≤2000)

注:练习2、练习3中,TTT是数据组数

莫比乌斯反演学习笔记(转载自An_Account大佬)的更多相关文章

  1. 莫比乌斯反演学习笔记+[POI2007]Zap(洛谷P3455,BZOJ1101)

    先看一道例题:[POI2007]Zap BZOJ 洛谷 题目大意:$T$ 组数据,求 $\sum^n_{i=1}\sum^m_{j=1}[gcd(i,j)=k]$ $1\leq T\leq 50000 ...

  2. 【笔记篇】不普及向——莫比乌斯反演学习笔记 && 栗题HAOI2011 Problem B

    Part0 广告(当然没有广告费) P.S. 这篇文章是边学着边用Typora写的...学完了题A了blog也就呼之欲出了~有latex化式子也非常方便...非常建议喜欢Markdown的dalao们 ...

  3. 【bzoj2440】【bzoj3994】莫比乌斯反演学习

    哇..原来莫比乌斯代码这么短..顿时感觉逼格-- 写了这道题以后,才稍稍对莫比乌斯函数理解了一些 定理:和是定义在非负整数集合上的两个函数,并且满足条件,那么我们得到结论 在上面的公式中有一个函数,它 ...

  4. js学习笔记—转载(闭包问题)

    ---恢复内容开始--- 闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现.     一.变量的作用域 要理解闭包,首先必须理解Javascrip ...

  5. jqgrid学习笔记(转载)

    jqgrid中文帮助文档网址:http://blog.mn886.net/jqGrid/ jqgrid:用来做什么? jqgrid是web端前台表格控件,用它可以轻松将数据格式化显示,前后台用过aja ...

  6. 《C#高级编程》之委托学习笔记 (转载)

    全文摘自 http://www.cnblogs.com/xun126/archive/2010/12/30/1921551.html 写得不错,特意备份!并改正其中的错误代码..     正文: 最近 ...

  7. HACMP 学习笔记--转载自wangjialiang-csdn博客

    An41 教程: Ha: 初始阶段的规划最重要 第一部分:概念和模型 Ha 目标:掩盖和消除计划和非计划的宕机 Eliminate SPOF :消除单节点故障, single point of fai ...

  8. MySql学习笔记(转载)

    . 数值类型 -- a. 整型 ----------     类型            字节        范围(有符号位)     tinyint        1字节    - ~        ...

  9. 非常详细的 Docker 学习笔记-转载

    文章链接 一.Docker 简介 Docker 两个主要部件: Docker: 开源的容器虚拟化平台 Docker Hub: 用于分享.管理 Docker 容器的 Docker SaaS 平台 --  ...

随机推荐

  1. Jmeter响应内容显示乱码问题的解决办法

    Jmeter在访问接口的时候,响应内容如果有中文可能会显示乱码,原因应该是响应页面没有做编码处理,jmeter默认按照ISO-8859-1编码格式进行解析. 下面把解决步骤列一下: 现象:jmeter ...

  2. pm2 观察报错时 pm2 start app.js --watch

    pm2 start app.js --watch[PM2][ERROR] Script already launched, add -f option to force re-execution

  3. python之路----继承的抽象类和接口类

    抽象类与接口类 接口类 继承有两种用途: 一:继承基类的方法,并且做出自己的改变或者扩展(代码重用) 二:声明某个子类兼容于某基类,定义一个接口类Interface,接口类中定义了一些接口名(就是函数 ...

  4. MySQL笔记(五)MySQL 角色与SQL CHECK约束

    MySQL ROLE MySQL 8.0 Reference Manual  /  Security  /  MySQL User Account Management  /  Using Roles ...

  5. http://bugs.mysql.com/bug.php?id=72123

    今天某个环境发生了这个bug. http://bugs.mysql.com/bug.php?id=72123

  6. 20145205武钰_Exp5 MSF基础应用

    20145205武钰_Exp5 MSF基础应用 实验后回答问题 exploit:这个词本身只是利用,但是它在黑客眼里就是漏洞利用.有漏洞不一定就有Exploit(利用).有Exploit就肯定有漏洞. ...

  7. 20145321《网络对抗技术》逆向与Bof基础

    20145321<网络对抗技术>逆向与Bof基础 实践目标 本次实践的对象是一个名为pwn1的linux可执行文件. 该程序正常执行流程是:main调用foo函数,foo函数会简单回显任何 ...

  8. UVa 10635 Prince and Princess - 动态规划

    讲一下题目大意,就是有两个长度为p + 1和q + 1的序列,求它们的LCS. 如果用O(pq)的算法对于这道题来说还是太慢了.所以要另外想一些方法.注意到序列中的所有元素都不相同,所以两个序列中数对 ...

  9. DTMF在VOIP中的解决方案

    双音多频DTMF(Dual Tone Multi-Frequency)信令,因其提供更高的拨号速率,迅速取代了传统转盘式电话机使用的拨号脉冲信令.DTMF也应用在交互式控制中,诸如语言菜单.语言邮件. ...

  10. BZOJ 1049 数字序列(LIS)

    题目链接:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1049 题意:给出一个数列A,要求:(1)修改最少的数字使得数列严格递增:(2)在( ...