判断素数的几种方法
介绍
1、素数计算函数:令小于等于 \(x\) 的素数个数为函数 \(pi(x)\),则随着 \(x\) 的增大,\(pi(x)\) 趋近于 \(\frac{x}{lnx}\)。
素数判断
1、埃氏筛:\(O(sqrt(n))\)
inline bool ispreim(i64 x) {
if (x == 0 || x == 1) return false;
for (i64 i = 2; i <= x / i; i++) {
if (x % i == 0) return false;
}
return true;
}
2、\(Miller-Rabin\) 筛:\(O(log(n))\)
struct MR{
inline i64 mul(i64 a, i64 b, i64 m) {
return static_cast<i128>(a) * b % m;
}
inline i64 qp(i64 a, i64 b, i64 m) {
i64 res = 1 % m;
for (; b; b >>= 1, a = mul(a, a, m))
if (b & 1)
res = mul(res, a, m);
return res;
}
inline bool isprime(i64 n) {
if (n < 2)
return false;
static constexpr i64 A[] = {2, 3, 5, 7, 11, 13, 17, 19, 23};
i64 s = __builtin_ctzll(n - 1);
i64 d = (n - 1) >> s;
for (auto a : A) {
if (a == n)
return true;
i64 x = qp(a, d, n);
if (x == 1 || x == n - 1)
continue;
bool ok = false;
for (i64 i = 0; i < s - 1; ++i) {
x = mul(x, x, n);
if (x == n - 1) {
ok = true;
break;
}
}
if (!ok)
return false;
}
return true;
}
};
3、线性筛也叫欧拉筛 :\(O(n)\)的预处理时间
模版:洛谷P3383。
struct pre{
int N;
vector<i64> preim;
vector<i64> a;
pre(int N_) : a(N_ + 1) {
N = N_;
for (i64 i = 2; i <= N; i++) {
if (!a[i]) {
a[i] = i;
preim.push_back(i);
}
for (auto p : preim) {
if (i * p > N) break;
a[i * p] = p;
if (a[i] == p) {
break;
}
}
}
}
inline bool ispreim(i64 x) {
return (a[x] == x && x != 0);
}
};

浙公网安备 33010602011771号