src/jiangly/math/04-Mu-Sieve.hpp
Code
/** 莫比乌斯函数筛(莫比乌斯函数/反演)
* 2023-03-04: https://atcoder.jp/contests/tupc2022/submissions/39391116
**/
std::unordered_map<int, Z> fMu;
constexpr int N = 1E7;
std::vector<int> minp, primes;
std::vector<Z> mu;
void sieve(int n) {
minp.assign(n + 1, 0);
mu.resize(n);
primes.clear();
mu[1] = 1;
for (int i = 2; i <= n; i++) {
if (minp[i] == 0) {
mu[i] = -1;
minp[i] = i;
primes.push_back(i);
}
for (auto p : primes) {
if (i * p > n) {
break;
}
minp[i * p] = p;
if (p == minp[i]) {
break;
}
mu[i * p] = -mu[i];
}
}
for (int i = 1; i <= n; i++) {
mu[i] += mu[i - 1];
}
}
Z sumMu(int n) {
if (n <= N) {
return mu[n];
}
if (fMu.count(n)) {
return fMu[n];
}
if (n == 0) {
return 0;
}
Z ans = 1;
for (int l = 2, r; l <= n; l = r + 1) {
r = n / (n / l);
ans -= (r - l + 1) * sumMu(n / l);
}
return ans;
}
#line 1 "src/jiangly/math/04-Mu-Sieve.hpp"
/** 莫比乌斯函数筛(莫比乌斯函数/反演)
* 2023-03-04: https://atcoder.jp/contests/tupc2022/submissions/39391116
**/
std::unordered_map<int, Z> fMu;
constexpr int N = 1E7;
std::vector<int> minp, primes;
std::vector<Z> mu;
void sieve(int n) {
minp.assign(n + 1, 0);
mu.resize(n);
primes.clear();
mu[1] = 1;
for (int i = 2; i <= n; i++) {
if (minp[i] == 0) {
mu[i] = -1;
minp[i] = i;
primes.push_back(i);
}
for (auto p : primes) {
if (i * p > n) {
break;
}
minp[i * p] = p;
if (p == minp[i]) {
break;
}
mu[i * p] = -mu[i];
}
}
for (int i = 1; i <= n; i++) {
mu[i] += mu[i - 1];
}
}
Z sumMu(int n) {
if (n <= N) {
return mu[n];
}
if (fMu.count(n)) {
return fMu[n];
}
if (n == 0) {
return 0;
}
Z ans = 1;
for (int l = 2, r; l <= n; l = r + 1) {
r = n / (n / l);
ans -= (r - l + 1) * sumMu(n / l);
}
return ans;
}
Back to top page