cp-library

C++ Library for Competitive Programming

View the Project on GitHub emthrm/cp-library

:question: メビウス関数 (Möbius function) 約数版
(include/emthrm/math/mobius_mu_focusing_on_divisor.hpp)

メビウス関数 (Möbius function)

$n \in \mathbb{N}^+$ に対して

\[\mu(n) \mathrel{:=} \begin{cases} 0 & (\exists p \in \mathbb{P},\ n \equiv 0 \pmod{p^2}), \\ (-1)^{\# \lbrace \text{相異なる素因数} \rbrace} & (\text{otherwise}) \end{cases}\]

で定義される $\mu(n)$ である。

が成り立つ。

メビウスの反転公式 (Möbius inversion formula)

\[f(n) = \sum_{d \mid n} g(d) \implies g(n) = \sum_{d \mid n} \mu \left(\frac{n}{d} \right) f(d) = \sum_{d \mid n} \mu(d) f \left(\frac{n}{d} \right)\]

時間計算量

  時間計算量
  $O(\sqrt{N})$
約数版  
数表 $O(N\log{\log{N}})$
数表2 $O\left(\sqrt{H}\log{\log{H}} + \frac{(H - L)\sqrt{H}}{\log{H}}\right)$ ?

仕様

名前 戻り値
int mobius_mu(long long n); $\mu(n)$

約数版

名前 戻り値 備考
template <typename T>
std::map<T, int> mobius_mu_focusing_on_divisor(T n);
$\lbrace n \text{ の約数 } d, \mu(d) \rbrace$ キーとして存在しないときは値 $0$ である。

数表

名前 戻り値
std::vector<int> mobius_mu_init(const int n); メビウス関数 $\mu(i)$ ($1 \leq i \leq n$) の数表
std::vector<int> mobius_mu_init2(const long long low, const long long high); メビウス関数 $\mu(i)$ ($\mathrm{low} \leq i < \mathrm{high}$) の数表

参考文献

TODO

Submissons

Verified with

Code

#ifndef EMTHRM_MATH_MOBIUS_MU_FOCUSING_ON_DIVISOR_HPP_
#define EMTHRM_MATH_MOBIUS_MU_FOCUSING_ON_DIVISOR_HPP_

#include <bit>
#include <map>
#include <vector>

namespace emthrm {

template <typename T>
std::map<T, int> mobius_mu_focusing_on_divisor(T n) {
  std::vector<T> primes;
  for (T i = 2; i * i <= n; ++i) {
    if (n % i == 0) [[unlikely]] {
      primes.emplace_back(i);
      while (n % i == 0) n /= i;
    }
  }
  if (n > 1) primes.emplace_back(n);
  const int p = primes.size();
  std::map<T, int> mu;
  for (unsigned int i = 0; i < (1 << p); ++i) {
    T d = 1;
    for (int j = 0; j < p; ++j) {
      if (i >> j & 1) d *= primes[j];
    }
    mu[d] = (std::popcount(i) & 1 ? -1 : 1);
  }
  return mu;
}

}  // namespace emthrm

#endif  // EMTHRM_MATH_MOBIUS_MU_FOCUSING_ON_DIVISOR_HPP_
#line 1 "include/emthrm/math/mobius_mu_focusing_on_divisor.hpp"



#include <bit>
#include <map>
#include <vector>

namespace emthrm {

template <typename T>
std::map<T, int> mobius_mu_focusing_on_divisor(T n) {
  std::vector<T> primes;
  for (T i = 2; i * i <= n; ++i) {
    if (n % i == 0) [[unlikely]] {
      primes.emplace_back(i);
      while (n % i == 0) n /= i;
    }
  }
  if (n > 1) primes.emplace_back(n);
  const int p = primes.size();
  std::map<T, int> mu;
  for (unsigned int i = 0; i < (1 << p); ++i) {
    T d = 1;
    for (int j = 0; j < p; ++j) {
      if (i >> j & 1) d *= primes[j];
    }
    mu[d] = (std::popcount(i) & 1 ? -1 : 1);
  }
  return mu;
}

}  // namespace emthrm
Back to top page