You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

4.0 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

莫比乌斯函数

https://www.cnblogs.com/letlifestop/p/10262757.html

// https://blog.csdn.net/qq_42887171/article/details/95237740

要学习莫比乌斯函数需要学习 到 积性函数,深度理解 欧拉筛

一、积性函数

1. 定义

积性函数:若gcd(a,b)=1,且满足f(a*b)=f(a)*f(b),则称f(x)积性函数

完全积性函数:对于任意正整数ab,都满足f(a*b)=f(a)*f(b),则称f(x)完全积性函数

2. 性质

  1. f(n),g(n)均为积性函数,则函数h(n)=f(n)*g(n)也是积性函数

  2. f(n)为积性函数,则函数c*f(n)(c是常数)也是积性函数,反之一样

  3. 任何积性函数都能应用线性筛,在O(n)时间内求出1\sim n项(莫比乌斯函数要用到),像素数,欧拉函数等都是 积性函数

二、莫比乌斯函数

1. 用途

我们举例一道经典的应用题,求1N中与a互质的数的个数:根据容斥原理,设S_i1N中和a有公因子i的数的个数,答案为NS_2-S_3-S_5-S_7...+S_{2,3}+S_{3,5}+S_{2,5}...,可以发现,其答案为\large \displaystyle \sum_{i=1}^{N}\mu(i)*S_i

:在使用容斥原理解决计数问题时,莫比乌斯函数的值就是每一项的系数,要么是1,要么是-1。这是因为莫比乌斯函数在容斥原理中的作用就是用来表示每个子集合的权重,从而在计算中起到排除重复计数的作用。

2. 定义

莫比乌斯函数是以19世纪的数学家亚当·莫比乌斯的名字命名的。它是数论中的一个重要函数,通常用符号 μ(n) 表示。

莫比乌斯函数的返回值有三种情况

  • ① 若n=1,μ(n) =1

  • ② 若n存在有大于1方数因数(如4(2平方)9(3的平方)27(3的立方),则μ(n) =0

  • μ(n) 的结果取决于n根据 算数基本定理 分解的 质因数个数的奇偶性 来判断。比如n=357就只有一个质因数所以为μ(n)=-1n=6,15,21μ(n)就为1

3. 求单个数字的莫比乌斯函数值

//单个数的莫比乌斯函数
int getmob(LL x) {
    int sum = 0;
    for (LL i = 2; i <= x / i; i++) { //从2开始一直到 sqrt(x),枚举所有可能存的小因子
        int cnt = 0;
        if (x % i == 0) {                     //如果x可以整除i
            while (x % i == 0) cnt++, x /= i; //计数并且不断除掉这个i因子
            if (cnt > 1) return 0;            //如果某个因子存在两个及以上个则返回0
            sum++;                            //记录因子个数
        }
    }
    if (x != 1) sum++;         //如果还存在另一个大因子,那么因子个数+1
    return (sum & 1) ? -1 : 1; //奇数个因子,返回-1,否则返回1
}

4.枚举倍数求莫比乌斯函数(埃氏筛)

//枚举倍数求莫比乌斯函数
LL mu[N] , sum[N];
void mobius(LL x) {
    mu[1] = 1;
    for (LL i = 1; i <= x; i++)
        for (LL j = i + i; j <= x; j += i)
            mu[j] -= mu[i];
    // 维护u(x)前缀和
    for (LL i = 1; i <= n; i++) sum[i] = sum[i - 1] + mu[i];
}

5.枚举约数求莫比乌斯函数(欧拉筛)

视频讲解

LL mu[N] , sum[N];
int primes[N], cnt;
bool st[N];
void get_mobius2(LL n) {
    mu[1] = 1;
    for (LL i = 2; i <= n; i++) {
        if (!st[i]) {
            primes[cnt++] = i;
            mu[i] = -1;
        }
        for (LL j = 0; primes[j] <= n / i; j++) {
            LL t = primes[j] * i;
            st[t] = true;
            if (i % primes[j] == 0) {
                mu[t] = 0;
                break;
            }
            mu[t] = mu[i] * -1;
        }
    }
     // 维护u(x)前缀和
    for (LL i = 1; i <= n; i++) sum[i] = sum[i - 1] + mu[i];
}