[莫比乌斯反演的若干技巧]

来源:互联网 发布:随身带着淘宝去异界295 编辑:程序博客网 时间:2024/06/07 13:21

莫比乌斯反演的若干性质:
这里写图片描述

F(n)和f(n)是定义在非负整数集合上的两个函数

其一般描述为(约数和
F(n)=d|nf(d) =>f(n)=d|nμ(d)F(nd)

另一种描述为(倍数和
F(n)=n|df(d)=>f(n)=n|dμ(dn)F(d)

mu(x),当x由y个互质的数相乘得到时,当y为奇数,mu(x)=-1,y为偶数,mu(x)=1;否则mu(x)=0;


莫比乌斯反演的一些技巧:
关于gcd求和(求gcd的值)
https://www.zybuluo.com/ruanxingzhi/note/753117
(orz

关于F与f
如果f中存在[xxx=d]的话,那么F中应当有一个[d|xxx]的状况,然后就能倍数和乱搞。


有关μ(x)的用法

对于任意正整数n
这里写图片描述
所以对于任意gcd(i,j)==k的时候,都可以把这个k取出来,然后化成这个形式,然后对于每个d,d|gcd(i,j)时都提供mu(d)的贡献。然后分段求和,往往能够得到一个式子,有着较为优秀的复杂度。
(注意显然这个式子只能求gcd(i,j)=k的个数,无法求gcd(i,j)的值

因为mu是积性函数,所以可以线性筛得到mu的值
模板为

    mu[1]=1;    for(int i=2;i<=n;++i)    {        if(!is[i]) prime[++prime[0]]=i,mu[i]=-1;        for(int j=1;j<=prime[0]&&i*prime[j]<=n;++j)        {            is[i*prime[j]]=1;            if(!(i%prime[j]))            {                mu[i*prime[j]]=0;;                break;            }            mu[i*prime[j]]=-mu[i];        }    }

phi的一些用法
x=d|xϕ(d)
所以面对gcd(i,j)求值问题时,可以把gcd(i,j)转化为以上问题,用phi来做。
又有
phi[i]=d|kdμ(kd),这个问题的转化我不会用。

求phi的板子

inline void get_phi(){    phi[1]=1;    for (int i=2;i<=n;++i){        if (!p[i]){            prime[++prime[0]]=i;            phi[i]=i-1;        }        for (int j=1;j<=prime[0]&&i*prime[j]<=n;++j){            p[i*prime[j]]=1;            if (i%prime[j]==0){                phi[i*prime[j]]=phi[i]*prime[j];                break;            }            else              phi[i*prime[j]]=phi[i]*(prime[j]-1);        }        phi[i]+=phi[i-1];    }}