This documentation is automatically generated by online-judge-tools/verification-helper
#include "src/math/linearSieve.hpp"
線形篩のアルゴリズムにより、 入力で与えた非負整数 $n$ 以下の最小素因数を列挙します。
素因数分解や約数列挙のクエリがたくさん飛んでくる場合や、素因数で小さいサイズにしていくタイプの動的計画法で利用できたりします。
コンストラクタ
(1) zawa::linearSieve()
(2) zawa::linearSieve(std::size_t n)
(1)
デフォルトコンストラクタ
(2)
1以上n
以下の最小素因数を列挙する
メンバ関数
factorize
std::vector<std::pair<int, int>> factorize(int x)
$x$ を素因数分解する。
(first, second) = 素因数、次数
である制約
$1\ \le\ x\ \le\ n$
計算量
$O(\log x)$ (多分 <- カス!)
divisor
std::vector<int> divisor(int x)
$x$ の約数を列挙する
制約 :
$1\ \le\ x\ \le\ n$
計算量
$O(\log^2 x)$ (多分 <- カス!)
enumPrime
std::vector<int> enumPrime()
isPrime
bool isPrime(int x)
$x$ が素数かを判定します。
制約
$1\ \le\ x\ \le\ n$
計算量
O(1)$
numPrime
int numPrime()
$n$ 以下の素数の個数を返します
計算量
$O(1)$
operator
[]
int [](int x)
$x$ の最小素因数を返します。
制約
$1\ \le\ x\ \le\ n$
計算量
$O(1)$
#pragma once
#include <vector>
#include <utility>
namespace zawa {
class linearSieve {
private:
std::vector<int> divs;
std::vector<int> primes;
public:
linearSieve() {}
linearSieve(std::size_t n) : divs(n + 1, 1) {
for (std::size_t i = 2 ; i < n + 1 ; i++) {
if (divs[i] == 1) {
divs[i] = i;
primes.push_back((int)i);
}
for (const auto& p : primes) {
if (p * i > n or p > divs[i]) {
break;
}
divs[p * i] = p;
}
}
}
std::vector<std::pair<int, int>> factorize(int x) {
std::vector res(0, std::pair(0, 0));
while (x > 1) {
res.emplace_back(divs[x], 0);
while (divs[x] == res.back().first) {
x /= divs[x];
res.back().second++;
}
}
return res;
}
std::vector<int> divisor(int x) {
std::vector res(1, 1);
for (const auto& [p, q] : factorize(x)) {
std::size_t now = res.size();
for (std::size_t i = 0 ; i < now ; i++) {
int mul = p;
for (int _ = 0 ; _ < q ; _++) {
res.emplace_back(res[i] * mul);
mul *= p;
}
}
}
return res;
}
std::vector<int> enumPrime() {
return primes;
}
int numPrime() {
return (int)primes.size();
}
bool isPrime(int x) {
return (x != 0 and x != 1 and divs[x] == x);
}
int operator[](int x) {
return divs[x];
}
};
}
#line 2 "src/math/linearSieve.hpp"
#include <vector>
#include <utility>
namespace zawa {
class linearSieve {
private:
std::vector<int> divs;
std::vector<int> primes;
public:
linearSieve() {}
linearSieve(std::size_t n) : divs(n + 1, 1) {
for (std::size_t i = 2 ; i < n + 1 ; i++) {
if (divs[i] == 1) {
divs[i] = i;
primes.push_back((int)i);
}
for (const auto& p : primes) {
if (p * i > n or p > divs[i]) {
break;
}
divs[p * i] = p;
}
}
}
std::vector<std::pair<int, int>> factorize(int x) {
std::vector res(0, std::pair(0, 0));
while (x > 1) {
res.emplace_back(divs[x], 0);
while (divs[x] == res.back().first) {
x /= divs[x];
res.back().second++;
}
}
return res;
}
std::vector<int> divisor(int x) {
std::vector res(1, 1);
for (const auto& [p, q] : factorize(x)) {
std::size_t now = res.size();
for (std::size_t i = 0 ; i < now ; i++) {
int mul = p;
for (int _ = 0 ; _ < q ; _++) {
res.emplace_back(res[i] * mul);
mul *= p;
}
}
}
return res;
}
std::vector<int> enumPrime() {
return primes;
}
int numPrime() {
return (int)primes.size();
}
bool isPrime(int x) {
return (x != 0 and x != 1 and divs[x] == x);
}
int operator[](int x) {
return divs[x];
}
};
}