結果
| 問題 |
No.8030 ミラー・ラビン素数判定法のテスト
|
| ユーザー |
|
| 提出日時 | 2023-07-23 14:58:08 |
| 言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 240 ms / 9,973 ms |
| コード長 | 2,042 bytes |
| コンパイル時間 | 1,597 ms |
| コンパイル使用メモリ | 167,032 KB |
| 実行使用メモリ | 6,948 KB |
| 最終ジャッジ日時 | 2024-09-24 16:24:51 |
| 合計ジャッジ時間 | 3,072 ms |
|
ジャッジサーバーID (参考情報) |
judge1 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 10 |
ソースコード
#include <bits/stdc++.h>
using namespace std;
//g++ temp.cpp -DLOCAL でコンパイルする
struct Miller_Rabin {
unsigned long long mul_mod(unsigned long long a, unsigned long long b, unsigned long long m) {
unsigned long long ans = 0;
#ifdef LOCAL
if(a > b) std::swap(a, b);
while(b){
if(b & 1){
ans += a;
if(ans >= m) ans -= m;
}
if((a <<= 1) >= m) a -= m;
b >>= 1;
}
#else
ans = (unsigned long long)((__int128)(a) * (__int128)(b) % m);
#endif
return ans;
}
unsigned long long pow_mod(unsigned long long x, unsigned long long n, unsigned long long m) {
if (m == 1) return 0;
unsigned long long r = 1;
unsigned long long y = x % m;
while (n) {
if (n & 1) r = mul_mod(r, y, m);
y = mul_mod(y, y, m);
n >>= 1;
}
return r;
}
bool is_prime(unsigned long long n) {
if (n <= 1) return false;
if (n == 2) return true;
if (n % 2 == 0) return false;
unsigned long long d = n - 1;
while (d % 2 == 0) d /= 2;
static long long bases[2][7] = {{2, 6, 61},
{2, 325, 9375, 28178, 450775, 9780504, 1795265022}};
for (long long a : bases[d > 4759123141]) {
unsigned long long t = d;
unsigned long long y = pow_mod(a, t, n);
if(a % n){
while (t != n - 1 && y != 1 && y != n - 1) {
y = mul_mod(y, y, n);
t <<= 1;
}
}
if (y != n - 1 && t % 2 == 0) return false;
}
return true;
}
};
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
Miller_Rabin MR;
int T;
cin >> T;
while(T--){
unsigned long long v;
cin >> v;
cout << v << ' ' << MR.is_prime(v) << '\n';
}
}