#include using namespace std; typedef long long LL; const int N = 1e5 + 10; int n = 27; //筛法求莫比乌斯函数(枚举约数) 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]; } //最简筛法求莫比乌斯函数(枚举倍数) void get_mobius1(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]; } //单个数的莫比乌斯函数 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 } int main() { //筛法求莫比乌斯函数 get_mobius1(n); 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_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; }