4.0 KiB
莫比乌斯函数
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)
为 积性函数
完全积性函数:对于任意正整数a,b
,都满足f(a*b)=f(a)*f(b)
,则称f(x)
为 完全积性函数
2. 性质
-
若
f(n),g(n)
均为积性函数,则函数h(n)=f(n)*g(n)
也是积性函数 -
若
f(n)
为积性函数,则函数c*f(n)
(c
是常数)也是积性函数,反之一样 -
任何积性函数都能应用线性筛,在
O(n)
时间内求出1\sim n
项(莫比乌斯函数要用到),像素数,欧拉函数等都是 积性函数。
二、莫比乌斯函数
1. 用途
我们举例一道经典的应用题,求1
到N
中与a
互质的数的个数:根据容斥原理,设S_i
为1
到N
中和a
有公因子i
的数的个数,答案为N−S_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=3,5,7
就只有一个质因数所以为μ(n)=-1
,n=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];
}