From 37077ea87bcdccefda7cdd2e6e09961ae87bbd2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E6=B5=B7?= <10402852@qq.com> Date: Fri, 15 Dec 2023 17:01:58 +0800 Subject: [PATCH] 'commit' --- TangDou/Topic/mobius.cpp | 59 +++++++++++++++-------------- TangDou/Topic/莫比乌斯函数.md | 20 ++++++---- 2 files changed, 43 insertions(+), 36 deletions(-) diff --git a/TangDou/Topic/mobius.cpp b/TangDou/Topic/mobius.cpp index 0289ae0..97aa2da 100644 --- a/TangDou/Topic/mobius.cpp +++ b/TangDou/Topic/mobius.cpp @@ -4,9 +4,9 @@ using namespace std; typedef long long LL; const int N = 1e5 + 10; -int n = 27; +int n = 20; -//筛法求莫比乌斯函数(枚举约数) +// 筛法求莫比乌斯函数(枚举约数) LL mu[N], sum[N]; int primes[N], cnt; bool st[N]; @@ -31,7 +31,7 @@ void get_mobius2(LL n) { for (LL i = 1; i <= n; i++) sum[i] = sum[i - 1] + mu[i]; } -//最简筛法求莫比乌斯函数(枚举倍数) +// 最简筛法求莫比乌斯函数(枚举倍数) void get_mobius1(LL x) { mu[1] = 1; for (LL i = 1; i <= x; i++) @@ -39,42 +39,43 @@ void get_mobius1(LL x) { mu[j] -= mu[i]; } -//单个数的莫比乌斯函数 +// 单个数的莫比乌斯函数 int getmob(LL x) { int sum = 0; - for (LL i = 2; i <= x / i; i++) { //从2开始,一直到 sqrt(x),枚举所有可能存的小因子 + 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 % 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 + if (x != 1) sum++; // 如果还存在另一个大因子,那么因子个数+1 + return (sum & 1) ? -1 : 1; // 奇数个因子,返回-1,否则返回1 } int main() { - //筛法求莫比乌斯函数 - get_mobius1(n); + // 计算单个数字的莫比乌斯函数 + for (int i = 1; i <= n; i++) printf("%2d ", getmob(i)); + cout << endl; + for (int i = 1; i <= n; i++) printf("%2d ", i); - for (int i = 1; i <= n; i++) { - //计算单个数字的莫比乌斯函数 - cout << "mu1[" << i << "]=" << getmob(i) << endl; - cout << "mu1[" << i << "]=" << mu[i] << endl; - cout << "========================================" << endl; - } - //清空一下,继续测试 - memset(mu, 0, sizeof mu); + // 筛法求莫比乌斯函数 + // get_mobius1(n); + // for (int i = 1; i <= n; i++) + // cout << "mu1[" << i << "]=" << mu[i] << endl; - //测试枚举约数的筛法 - get_mobius2(n); + // //清空一下,继续测试 + // memset(mu, 0, sizeof mu); - for (int i = 1; i <= n; i++) { - //计算单个数字的莫比乌斯函数 - cout << "mu2[" << i << "]=" << getmob(i) << endl; - cout << "mu2[" << i << "]=" << mu[i] << endl; - cout << "========================================" << endl; - } + // //测试枚举约数的筛法 + // get_mobius2(n); + + // for (int i = 1; i <= n; i++) { + // //计算单个数字的莫比乌斯函数 + // cout << "mu2[" << i << "]=" << getmob(i) << endl; + // cout << "mu2[" << i << "]=" << mu[i] << endl; + // cout << "========================================" << endl; + // } return 0; } \ No newline at end of file diff --git a/TangDou/Topic/莫比乌斯函数.md b/TangDou/Topic/莫比乌斯函数.md index 816334f..1981e8e 100644 --- a/TangDou/Topic/莫比乌斯函数.md +++ b/TangDou/Topic/莫比乌斯函数.md @@ -34,16 +34,22 @@ https://www.cnblogs.com/letlifestop/p/10262757.html #### 2. 定义 -莫比乌斯函数是以$19$世纪的数学家亚当·莫比乌斯的名字命名的。它是数论中的一个重要函数,通常用符号 $μ(n)$ 表示。 +![](https://dsideal.obs.cn-north-1.myhuaweicloud.com/HuangHai/BlogImages/202312151650942.png) -**莫比乌斯函数的返回值有三种情况**: +莫比乌斯函数是个分段函数,它的意思: +- ① 当$n=1$时,莫比乌斯函数值为$1$ +- ② 当$n$为可以分解为许多素数并且这些质因子的次数都是$1$时,莫比乌斯值就是$-1$的 **质数因子个数的幂次方** +- ③ 除了这些情况剩余的情况莫比乌斯函数值都是$0$ -* ① 若$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$。 +前五十个数的莫比乌斯值. +![](https://dsideal.obs.cn-north-1.myhuaweicloud.com/HuangHai/BlogImages/202312151653968.png) +打印前$20$个数字的莫比乌斯函数值 + +```cpp {.line-numbers} +函数值 1 -1 -1 0 -1 1 -1 0 0 1 -1 0 -1 1 1 0 -1 0 -1 0 +数 字: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 +``` #### 3. 求单个数字的莫比乌斯函数值 ```cpp {.line-numbers}