結果
| 問題 |
No.8030 ミラー・ラビン素数判定法のテスト
|
| ユーザー |
|
| 提出日時 | 2020-12-21 09:09:51 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 2,076 bytes |
| コンパイル時間 | 2,043 ms |
| コンパイル使用メモリ | 196,428 KB |
| 最終ジャッジ日時 | 2025-01-17 05:26:16 |
|
ジャッジサーバーID (参考情報) |
judge5 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 4 WA * 6 |
ソースコード
#include <bits/stdc++.h>
#define int int64_t
using namespace std;
/**
* @brief 大きな mod 上の計算
* @note O(1)
*/
inline std::int64_t mod(std::int64_t a, std::int64_t m) {
return (a % m + m) % m;
}
/**
* @note O(1)
*/
inline std::int64_t mul(std::int64_t a, std::int64_t b, std::int64_t m) {
__int128_t am = mod(a, m), bm = mod(b, m);
return std::int64_t(am * bm % m);
}
/**
* @brief 累乗 : $a^n\bmod{m}$ ($m$ が大きい場合)
* @note O(\log{n}\log{m})
*/
std::int64_t mod_pow(std::int64_t a, std::int64_t n, std::int64_t m) {
a = mod(a, m);
std::int64_t res = 1;
while (n) {
if (n & 1) res = mul(res, a, m);
a = mul(a, a, m);
n >>= 1;
}
return res;
}
struct Random {
std::mt19937_64 mt;
Random() { mt.seed(std::chrono::steady_clock::now().time_since_epoch().count()); }
} rnd;
/**
* @brief 乱数 (数)
* @note O(1)
*/
template <typename T>
T random_number(const T a, const T b) {
assert(a < b);
if (std::is_integral<T>::value) {
std::uniform_int_distribution<T> dist(a, b - 1);
return dist(rnd.mt);
} else {
std::uniform_real_distribution<> dist(a, b);
return dist(rnd.mt);
}
}
/**
* @note O(1)
*/
template <typename T>
T random_number(const T b) {
return random_number(T(0), b);
}
/**
* @brief 素数判定 (ミラー・ラビン)
* @note O(k\log^3{n})
*/
bool is_prime(std::uint64_t n, std::uint32_t k = 20) {
if (n == 2) return true;
if (n < 2 || !(n & 1)) return false;
std::uint64_t d = n - 1;
while (!(d & 1)) d >>= 1;
for (std::uint32_t i = 0; i < k; ++i) {
std::uint64_t a = random_number((std::uint64_t)1, n), t = d, y = mod_pow(a, t, n);
while (t != n - 1 && y != 1 && y != n - 1) {
y = mod_pow(y, 2, n);
t <<= 1;
}
if (y != n - 1 && !(t & 1)) return false;
}
return true;
}
signed main() {
int n; cin >> n;
for (int i = 0; i < n; ++i) {
int x; cin >> x;
cout << x << " " << is_prime(x) << endl;
}
}