This documentation is automatically generated by online-judge-tools/verification-helper
View the Project on GitHub ebi-fly13/Library
#include "math/multiple_transform.hpp"
倍数に対してゼータ変換とメビウス変換を行う。 $O(N\log \log N)$
#pragma once #include <vector> #include "../math/eratosthenes_sieve.hpp" namespace ebi { struct multiple_transform { multiple_transform() = default; template <class mint> static std::vector<mint> zeta_transform(const std::vector<mint> &f) { int n = f.size() - 1; auto F = f; if (m < n) { while (m < n) m <<= 1; eratosthenes_sieve sieve(m); primes = sieve.prime_table(); } for (const auto &p : primes) { if (n < p) break; for (int i = n / p; i > 0; i--) F[i] += F[i * p]; } return F; } template <class mint> static std::vector<mint> mobius_transform(const std::vector<mint> &F) { int n = F.size() - 1; auto f = F; if (m < n) { while (m < n) m <<= 1; eratosthenes_sieve sieve(m); primes = sieve.prime_table(); } for (const auto &p : primes) { if (n < p) break; for (int i = 1; i * p <= n; i++) f[i] -= f[i * p]; } return f; } private: static int m; static std::vector<int> primes; }; int multiple_transform::m = 4; std::vector<int> multiple_transform::primes = {2, 3}; } // namespace ebi
#line 2 "math/multiple_transform.hpp" #include <vector> #line 2 "math/eratosthenes_sieve.hpp" #include <cassert> #include <cstdint> #line 6 "math/eratosthenes_sieve.hpp" /* reference: https://37zigen.com/sieve-eratosthenes/ */ namespace ebi { struct eratosthenes_sieve { private: using i64 = std::int_fast64_t; int n; std::vector<bool> table; public: eratosthenes_sieve(int _n) : n(_n), table(std::vector<bool>(n + 1, true)) { table[1] = false; for (i64 i = 2; i * i <= n; i++) { if (!table[i]) continue; for (i64 j = i; i * j <= n; j++) { table[i * j] = false; } } } bool is_prime(int p) { return table[p]; } std::vector<int> prime_table(int m = -1) { if (m < 0) m = n; std::vector<int> prime; for (int i = 2; i <= m; i++) { if (table[i]) prime.emplace_back(i); } return prime; } }; } // namespace ebi #line 6 "math/multiple_transform.hpp" namespace ebi { struct multiple_transform { multiple_transform() = default; template <class mint> static std::vector<mint> zeta_transform(const std::vector<mint> &f) { int n = f.size() - 1; auto F = f; if (m < n) { while (m < n) m <<= 1; eratosthenes_sieve sieve(m); primes = sieve.prime_table(); } for (const auto &p : primes) { if (n < p) break; for (int i = n / p; i > 0; i--) F[i] += F[i * p]; } return F; } template <class mint> static std::vector<mint> mobius_transform(const std::vector<mint> &F) { int n = F.size() - 1; auto f = F; if (m < n) { while (m < n) m <<= 1; eratosthenes_sieve sieve(m); primes = sieve.prime_table(); } for (const auto &p : primes) { if (n < p) break; for (int i = 1; i * p <= n; i++) f[i] -= f[i * p]; } return f; } private: static int m; static std::vector<int> primes; }; int multiple_transform::m = 4; std::vector<int> multiple_transform::primes = {2, 3}; } // namespace ebi