1.数论函数的卷积公式
(ƒ*g)(n)=Σd|nƒ(d)×g(n/d)
已知f*[1~n],g[1~n]
怎么求(f*g)[1~n]?
一个个求复杂度O(n根号n)
如何加速?
考虑更换枚举顺序(这点很重要,在接下来的一些求和运算中会用到)
枚举代码:
ll f[N],g[N],h[N]; void calc(int n) { for(int i=1;i*i<=n;i++) { h[i*j]+=f[i]*g[i]; for(int j=i+1;i*j<=n;j++) h[i*j]+=f[i]*g[j]+f[j]*g[i]; } }
这样子速度就会变为n log n
例子1:
求当a≤x≤b,c≤y≤d时,gcd(x,y)=1的个数
前缀和如图
式子为:
Σi=1n Σj=1m [gcd(i,j)=1]
[]意思:为真返回1否则返回0
联系到莫比乌斯函数μ(d)
Σd|n μ(d):
当n=1时它=1
否则=0
这两个是可以等效替换的:
Σi=1n Σj=1m Σd|gcd(i,j)μ(d)
交换枚举顺序,降到了线性复杂度:
对于这个东西:
d从1枚举到n时,可能的取值只有o(根号n)种
由于当1≤d≤根号n和根号n≤d≤n时,最多情况数都是