狄利克雷卷积
h(n)=(f∗g)(n)=∑i|nf(i)⋅g(ni)=∑ab=xf(a)⋅g(b)记为h=f∗g交换律f∗g=g∗f,显然由上式,交换仅仅是ab交换,相等结合律(f∗g)∗h=f∗(g∗h)分配律f∗(g+h)=f∗g+f∗h单位元f∗ε=f若f和g都是积性函数,则f∗g为积性函数f=g的充要条件是f∗h=g∗h,其中保证h(1)≠0若f∗g=ε,则f和g互为逆元积性函数必然有逆元,逆元也是积性函数
常见卷积公式
ε=μ∗1d=1∗1σ=id∗1φ∗1=id
积性函数线性筛
利用欧拉筛的方法,显然容易线性筛出任何积性函数
1 | void getf() |
式子1 质数,式子2 质数prime[j]的指数增加了一,式子3 互质
比如筛莫比乌斯函数时,式子1为-1,式子2为0,式子3为-f[i]
筛欧拉函数时,式子1为i-1,式子2为f[i]*prime[j],式子3为phi[i]*(prime[j]-1)
数论分块
含有⌊ni⌋的求和式,如∑ni=1⌊ni⌋⋅f(i),容易发现⌊ni⌋的取值只有√n种。设当前值的左界为l,有界为r,则一个方便的跳l、r的方式是l=r+1,r=n/(n/l)。如果f(x)能用求和公式表示,那么整个式子的值就能在O(√n)的时间复杂度内完成
做了一道模板题Luogu P2261,因为太显然了,就不单独发blog,这里也不贴代码了。
二维数论分块
min(n,m)∑i=1⌊ni⌋⋅⌊mi⌋
只是把跳√n次变成2√n次罢了,找n和m的跳跃点中最近的位置跳即可。
莫比乌斯反演
f(n)=∑d|ng(d)⟺g(n)=∑d|nμ(d)f(nd)f=g∗1⟺g=f∗μ
由前文狄利克雷卷积部分知识,显然。
如何应用
场景一
g(i)难求,但f(i)=∑d|ig(d)较容易求,则利用下式:f(i)=∑d|ig(d)⇒g(i)=∑d|if(id)⋅μ(d)
场景二
g(i)难求,但f(i)=⌊ni⌋∑d=1g(d⋅i)容易求,则利用下式f(i)=⌊ni⌋∑d=1g(d⋅i)⇒g(i)=⌊ni⌋∑d=1f(d⋅i)⋅μ(d)
技巧
等价变换:改变枚举顺序(内层外移)、变量替换等技巧
线性筛:线性处理各种信息
数论分块:重要工具
例1:
经过转化之后,问题的核心是
⌊nk⌋∑i=1⌊mk⌋∑j=1(gcd(i,j)==1)
解:
看到==1这种东西,首先想到单位元函数
原式=⌊nk⌋∑i=1⌊mk⌋∑j=1ε(gcd(i,j))=⌊nk⌋∑i=1⌊mk⌋∑j=1∑d|gcd(i,j)μ(d) 莫比乌斯反演=min⌊nk⌋,⌊mk⌋∑d=1μ(d)⌊mk⋅d⌋⌊nk⋅d⌋
其中推导的最后一步更换了枚举的变量。可以发现,倒数第二个式子中,对于每个d,当d|i或d|j时μ(d)都会被加一次,因此可以得到最终的式子。
而最终的式子显然可以在预处理出莫比乌斯函数的前缀和后通过上面提到的二维数论分块的思路来快速解决
例2
求
n∑i=1m∑j=1gcd(i,j)
解:
利用常见卷积的公式,
原式=n∑i=1m∑j=1∑d|gcd(i,j)φ(d)=∑d=1φ(d)⋅⌊nd⌋⋅⌊md⌋
接下来处理和例1相同
例3 SPOJ5971 LCMSUM
n∑i=1lcm(i,n)
3e5组询问,n范围1e6
解:
原式=n∑i=1i⋅ngcd(i,n)=∑d|nn∑i=1i⋅nd[gcd(i,n)==d]=n⋅∑d|n⌊nd⌋∑i=1id[gcd(i,nd)==1],改变枚举的变量i的意义=n⋅∑d|nd∑i=1i⋅[gcd(i,d)==1],由于枚举d和枚举nd等价=n⋅∑d|nd⋅φ(d)+[d==1]2,上文φ函数的性质一节中提到的公式=n2⋅(∑d|nφ(d)⋅d+1),推导显然
至此可以得到O(n)预处理出欧拉函数,O(√n)回答询问的方法。但是这样会TLE
考虑将答案函数预处理:显然可以在调和级数复杂度下做出来。总复杂度O(nlgn+T)
通过推导可以发现,∑d|nφ(d)⋅d是个积性函数,可以线性预处理,因此可以做到O(n+T),具体证明待补
例4
n∑i=1m∑j=1lcm(i,j)
解:
原式=n∑i=1m∑j=1i⋅jgcd(i,j)=n∑i=1m∑j=1i⋅jd[gcd(i,j)==d]=n∑d=1⌊nd⌋∑i=1⌊md⌋∑j=1i⋅j⋅d[gcd(i,j)==1]=n∑d=1d⋅⌊nd⌋∑i=1i⌊md⌋∑j=1j∑k|gcd(i,j)μ(k)=n∑k=1k2μ(k)n∑d=1d⌊ndk⌋∑i=1i⌊mdk⌋∑j=1j下面设f(x)=x∑i=1i,设T=nk=n∑T=1∑d|TT2d2dμ(Td)f(nT)f(mT)=n∑T=1f(nT)f(mT)⋅T∑d|Td⋅μ(d)其中F(x)=∑d|Td⋅μ(d)可以证明是一个积性函数,可以O(n)筛出来,前面部分数论分块即可
例5 SDOI2015 约数个数和
n∑i=1m∑j=1d(i⋅j)
解:
首先利用约数个数函数的重要性质d(i⋅j)=∑d|i∑d|j[gcd(i,j)==1]则原式=n∑i=1m∑j=1∑d|i∑d|j[gcd(i,j)==1]=n∑i=1m∑j=1i∑d=1μ(d)⋅⌊id⌋⋅⌊jd⌋=n∑d=1μ(d)⋅n∑i=1⌊id⌋⋅m∑j=1⌊jd⌋数论分块即可
例6 SDOI2017 数字表格
n∏i=1m∏j=1fib(gcd(i,j))n,m≤106,T≤1000,fib(0)=0
解:
只1是把问题放到了指数上罢了。斐波那契数列显然和数论要用的这些没什么大关系,所以先常规操作:
原式=n∏i=1m∏j=1f(d)[gcd(i,j)=d]=∏d=1⌊nd⌋∏i=1⌊md⌋∏j=1f(d)[gcd(i,j)=1]=∏d=1⌊nd⌋∏i=1⌊md⌋∏j=1∏k|gcd(i,j)f(d)μ(k)=∏d=1∏k=1⌊ndk⌋∏i=1⌊mdk⌋∏j=1f(d)μ(k)=n∏T=1∏d|Tf(d)⌊nT⌋⋅⌊mT⌋⋅μ(Td)乍一看似乎没法继续推下去了,考虑把不能数论分块的部分提出=n∏T=1(∏d|Tf(d)μ(Td))⌊nT⌋⋅⌊mT⌋其中括号内的部分可以求前缀积,指数数论分块即可
例7 BZOJ4407 于神之怒加强版
n∑i=1m∑j=1gcd(i,j)kn,m≤5⋅106,T≤2000
解:
原式=n∑d=1⌊nd⌋∑i=1⌊md⌋∑j=1dk⋅[gcd(i,j)=1]=n∑T=1⌊mT⌋⌊nT⌋∑d|Tdkμ(Td),常规操作可以发现右边的式子是σk∗μ,显然是积性函数,可以线性预处理出来。询问时数论分块
例8 BZOJ2820 YY的GCD
n∑i=1m∑j=1[gcd(i,j)∈prime]n,m≤107
解:
先常规操作,得原式=n∑T=1⌊nT⌋⋅⌊mT⌋∑k|T,k∈primeμ(Tk)右式可以预处理,由于处理次数是n∑p=1⌊np⌋[p∈prime],因此复杂度小于调和级数考虑质数个数粗略估计是nlgn,调和级数求和复杂度O(nlgn),因此复杂度应该是接近O(n)的
例9 HDU4944 FSF’s game
n∑i=1n∑j=i∑d|i,jijgcd(id,jd)T=500000,n≤500000
解:
首先看到这个gcd在分母上这个样子,很难受,同时形式很像是lcm,考虑转化
原式=n∑i=1n∑j=i∑d|gcd(i,j)d⋅lcm(i,j)=n∑d=1d2⌊nd⌋∑i=1⌊nd⌋∑j=ilcm(i,j)调换ij位置=n∑d=1d2⌊nd⌋∑i=1i∑j=1lcm(i,j)由例3,=n∑d=1d2⌊nd⌋∑i=1i2(∑k|ik⋅φ(k)+1)其中i右边的式子可以调和级数O(nlgn)求出,乘上i前缀和即可预处理出⌊nd⌋∑i=1i2(∑k|ik⋅φ(k)+1)将其记为f(⌊nd⌋),则原式=n∑d=1d2⋅f(⌊nd⌋),显然可以数论分块,但500000数据范围过大,考虑将f看作差分,对其求前缀和
1 | const int maxN=555555,maxn=500000; |
例10 HDU6428 Calculate
a∑i=1b∑j=1c∑k=1φ(gcd(i,j2,k3))
解:
这种复合的式子首先考虑将里面的利用莫比乌斯反演提出原式=a∑i=1b∑j=1c∑k=1∑d|gcd(i,j2,k3)(φ∗μ)(d)=∑d=1(φ∗μ)(d)a∑i=1b∑j=1c∑k=1[d|gcd(i,j2,k3)],内层外移=∑d=1(φ∗μ)(d)a∑i=1[d|i]b∑j=1[d|j2]c∑k=1[d|k3],显然到这里,我们发现前面的φ∗μ可以线性处理,后面的式子似乎没那么好做。将其单独拿出来考虑首先感受一下发现,似乎只要某个数是离散意义下的k√d的倍数,即是符合式子的用数学语言描述就是x∑i=1[d|ik]中,d|ik⇒对于d的质因数分解,∏jprime[j]⌈a[j]k⌉|i则x∑i=1[d|ik]=⌊x∏jprime[j]⌈a[j]k⌉⌋设分母为f(d),由于其积性,可以线性预处理
1 | void get(const unsigned &n) |