莫比乌斯反演
在学了几天之后一脸懵逼的参照诸位大佬和自己的一点点小理解写的总结
前言
据大佬说可能每一个刚开始接触莫比乌斯反演的OIer,都会厌恶这个神奇的东西。我是十分的感同身受,不仅这个式子又臭又长又烦人,而且μ函数很难理解。而且,莫比乌斯反演有一个预备知识:整数分块 http://www.cnblogs.com/peng-ym/p/8661118.html
最开始没看这个感觉题根本做不动。。。
先从莫比乌斯反演中最基础的莫比乌斯函数μ开始说起:
莫比乌斯函数
- 首先,莫比乌斯函数并不是什么很高大上的东西,它其实只是一个由容斥系数所构成的函数。μ(d)的定义是:
- 当d=1时,μ(d)=1;
- 当d=Πki=1pi且pi为互异素数时,μ(d)=(−1)k。(说直白点,就是d分解质因数后,没有幂次大于平方的质因子,此时函数值根据分解的个数决定);
- 只要当d含有任何质因子的幂次大于2,则函数值为0.
- 当然,莫比乌斯函数也有很多有趣的性质:
- 对于任意正整数nn,∑d|nμ(d)=[n=1]。([n=1]表示只有当n=1成立时,返回值为1;否则,值为0;(这个就是用μ是容斥系数的性质可以证明)(PS:公式都是复制的 但是这条最重要 )
- 对于任意正整数nn,∑d|nμ(d)d=ϕ(n)n。(这个性质很奇妙,它把欧拉函数和莫比乌斯函数结合起来,但是不会证。。。看了证明一脸懵逼,会用就行了)
- 程序实现可以在线性筛素数筛上略作修改,便可以筛出μ函数。
- 大佬那里偷来的线筛
void get_mu(int n)
{
mu[1]=1;
for(int i=2;i<=n;i++)
{
if(!vis[i]){prim[++cnt]=i;mu[i]=-1;}
for(int j=1;j<=cnt&&prim[j]*i<=n;j++)
{
vis[prim[j]*i]=1;
if(i%prim[j]==0)break;
else mu[i*prim[j]]=-mu[i];
}
}
}
莫比乌斯反演
- 解决完莫比乌斯函数的问题后,我们便迎来了重头戏莫比乌斯反演
- 定理:F(n)和f(n)是定义在非负整数集合上的两个函数,并且满足条件:
F(n)=∑d|nf(d)
那么存在一个结论:f(n)=∑d|nμ(d)F(⌊nd⌋)
这个定理就称作莫比乌斯反演定理。 - 莫比乌斯反演有另外的一种形式,当F(n)和f(n)满足:
F(n)=∑n|df(d)
可以推出:f(n)=∑n|dμ(dn)F(d)
- 感觉这个式子,可能在莫比乌斯反演中更加好用。