莫比乌斯函数

\(\mu(x)\)为莫比乌斯函数,定义为:\(\mu(x) = \begin{cases} 1, & \text{if } x = 1 \\ (-1)^k, & \text{if } x = p_1 p_2 \ldots p_k \\ 0, & \text{otherwise} \end{cases} \)


在进行整数分解后 \(n=\prod_{i=1}^k p_i^{c_i}\),其中\(p_i\)表示质因子而\(c_i\geq1\),上述定义表示:

  • \(n=1\)时,\(\mu(n)=1\)
  • \(n\neq1\)时,如果n的质因数分解中有某个质因子的次数超过1次,那么\(\mu(n)=0\),否则\(\mu(n)\)的值为-1的k次幂,其中k是n的不同质因子的个数


莫比乌斯函数与容斥有一定的联系,具体来说,其符号的交替性体现了容斥原理中的加减交替原则,例如:

  • 负号对应“减去被单个素数整除的项”(第一次减法)。

  • 正号对应“加回被两个素数乘积整除的项”(第二次加法)。

  • 零值对应“忽略被平方因子整除的项”(这些情况已被排除)。


计算欧拉函数\(\phi(n)\)(与n互质数的个数),利用莫比乌斯函数有:\(\phi(n)=n\sum_{d \mid n}\frac{\mu(d)}{d}\)
以计算\(\phi(6)\)为例,从容斥定理的角度:

  • 总数:6 个数。
  • 减去被 2 整除的数:6/2=3个(即2,4,6)
  • 减去被 3 整除的数:6/3=2 个(即3,6)
  • 但此时 6 被减去了两次,需要加回被 2×3 整除的数:6/6=1 个(即6)
  • 最终结果:6−3−2+1=2

以该公式的角度,带入并展开后可以发现就是相同的形式 \(\phi(n)=(6/1 * 1)+(6/2 * (-1))+(6/3 * (-1))+(6/6 * 1)=2\)
也就是莫比乌斯函数的符号和值,直接对应容斥定理中的操作:

  • μ(1)=1:初始总数(加法)
  • μ(2)=−1:减去被素数 2 整除的数
  • μ(3)=−1:减去被素数 3 整除的数
  • μ(6)=1:加回被 2×3 整除的数(修正重复减法)
  • 含平方因子的 d(如 4=2*2):μ(4)=0,直接忽略这些情况(因为它们已被计算,对答案并没有影响)


莫比乌斯函数是积性函数,也就是如果\(x=p_1^{\alpha_1}p_2^{\alpha_2}\ldots p_k^{\alpha_k}\)\(f(x)=f(p_1^{\alpha_1})f(p_2^{\alpha_2})\ldots f(p_k^{\alpha_k})\)


同时,莫比乌斯函数满足,\( \sum_{d \mid n} \mu(d) = \begin{cases} 1, & \text{if } n = 1 \\ 0, & \text{if } n \neq 1 \end{cases} \)
证明:

  • 首先,n=1,结论显然成立

  • 当n满足\(n=p^k\),也就是n为素数幂时,其因数只有\(1,p,p^2,\ldots,p^k\),而根据定义,有\(\mu(1)=1,\mu(p)=-1,\mu(p^i)=0\ (i\geq2,因为此时含有平方因子)\)
    从而\(\sum_{d \mid p^k}\mu(d)=1+(-1)+0+\ldots+0=0\)

  • 由莫比乌斯函数的积性,先将n分解为质因子的乘积\(n=p_1^{\alpha_1}p_2^{\alpha_2}\ldots p_k^{\alpha_k}\),如果存在\(k_i\geq2\),则表示存在平方因子,同时该质因子的\(\mu(p_i^{k_i})=0\),于是\(\mu(n)=0\)
    而对于无平方因子的n,由积性易得,若d是其中素因子子集的乘积,则\(\mu(d)=(-1)^{素因子个数}\)
    进而枚举n的因子进行莫比乌斯函数值求和时,相当于对每个素因子选或不选,于是有\(2^m\)个因数,利用二项式定理可得:\( \sum_{d \mid n} \mu(d) = \sum_{k=0}^{m} \binom{m}{k} (-1)^k = (1-1)^m = 0\)
    即只要满足\(n\geq2\),一定有\(\sum_{d \mid n} \mu(d) = 0\)


由此可以得到一个推论,gcd(a,b)=1(也就是a和b互质)等价于$ \sum_{d \mid gcd(a,b)} \mu(d) = 1$


莫比乌斯函数的求法:
由于莫比乌斯函数是一个积性函数,因此可以线性筛莫比乌斯函数


例:
cf 2037G
有n个点,每个点有权值a[i],两个点i,j之间存在一条有向边当且仅当\(i<j,gcd(a[i],a[j])\neq1\)
问从点1到点n的不同路径的总数,模数为998244353

与gcd相关联的可以考虑使用莫比乌斯函数
如果我们能够建出整个图,那么是好算的,直接做一个方案数dp即可,但问题在于如何建图,也就是判断两个点之间是否存在边
为解决这个问题,可以对莫比乌斯函数进行调整:
设定一个新函数c,初始c全为1,但c[1]=0,然后通过类似莫比乌斯函数的筛法(c[j]-=c[i]的迭代),得到修正后的莫比乌斯函数
最终c[d]的值和标准莫比乌斯函数的关系为:\( c[d] = \begin{cases} 0, & \text{if } d = 1 \ or \ \text{存在平方因子 } \\ -\mu(d), & \text{otherwise } \end{cases} \)
进行这样修正的原因是,这题需要统计的是非互质对的贡献,因此若两个数的最大公约数是1,那么通过设定c[1]=0使得它们的贡献被排除
进而我们可以通过枚举因子的方式来计算方案数

void solve() {
    int n;
    cin>>n;
    vector<int> a(n);
    for(int i=0;i<n;i++){
        cin>>a[i];
    }
    int m=*max_element(a.begin(),a.end());
    vector<Z> c(m+1,1);
    c[1]=0;
    for(int i=1;i<=m;i++){
        for(int j=2*i;j<=m;j+=i){
            c[j]-=c[i];
        }
    }
    vector<vector<int>> ds(m+1);
    for(int i=1;i<=m;i++){// 枚举因子
        if(!c[i].val()){
            continue;
        }
        for(int j=i;j<=m;j+=i){
            ds[j].emplace_back(i);
        }
    }
    vector<Z> g(m+1,0);
    vector<Z> f(n);
    for(int i=0;i<n;i++){
        for(auto d:ds[a[i]]){
            f[i]+=g[d]*c[d];
        }
        if(i==0){
            f[i]+=1;
        }
        for(auto d:ds[a[i]]){
            g[d]+=f[i];
        }
    }
    cout<<f[n-1]<<'\n';
}

g[d]累积了所有满足以下条件的路径计数:

  • 路径起点是城市1
  • 路径终点是某个已处理过的城市i(满足a[i]能被d整除,也就是计算时满足当前计算的数和a[i]有公因子d)

而f[i]+=g[d]*c[d]实际上使用了上面提到的容斥的思想进行转移
假设我们考虑因子6(6 = 2 × 3):c[6] = -1(因为6有2个不同质因子)

  • 如果不乘以c[d]:在枚举的过程中
  • 路径会通过因子2被计算一次
  • 路径会通过因子3再被计算一次
  • 这导致"可以通过公因子2或3连接的路径"被重复计算了

乘以c[6]=-1后:对于那些"同时"通过2和3(即通过6)连接的路径,我们减去这部分贡献,消除重复计数,从而得到正确的方案数

posted @ 2025-04-03 15:20  rdcamelot  阅读(120)  评论(0)    收藏  举报