結果
| 問題 |
No.8030 ミラー・ラビン素数判定法のテスト
|
| ユーザー |
|
| 提出日時 | 2021-09-01 16:46:40 |
| 言語 | C (gcc 13.3.0) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 2,013 bytes |
| コンパイル時間 | 1,554 ms |
| コンパイル使用メモリ | 31,104 KB |
| 実行使用メモリ | 6,912 KB |
| 最終ジャッジ日時 | 2024-11-27 21:58:44 |
| 合計ジャッジ時間 | 78,602 ms |
|
ジャッジサーバーID (参考情報) |
judge2 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | WA * 3 TLE * 7 |
ソースコード
#include <stdint.h>
#include <stdio.h>
#include <stdbool.h>
typedef int64_t i64;
typedef __int128_t i128;
typedef uint64_t u64;
typedef __uint128_t u128;
typedef u64 m64;
u64 mul_inv(u64 n) {
u64 x = 1;
for (int i = 6; i > 0; --i) {
x = x * (2 - x * n);
}
return x;
}
m64 calc_mod(u64 m) {
return m;
}
m64 calc_inv(u64 m) {
return mul_inv(calc_mod(m));
}
m64 calc_r2(u64 m) {
return -(u128)(calc_mod(m)) % calc_mod(m);
}
m64 MR(u128 x, m64 mod, m64 inv) {
m64 y = (u64)(x >> 64) - (u64)(((u128)((u64)x * inv) * mod) >> 64);
return (i64)y < 0 ? y + mod : y;
}
m64 toM64(u64 w, m64 mod, m64 inv, m64 r2) { return MR((u128)w * r2, mod, inv); }
u64 fromM64(m64 x, m64 mod, m64 inv) { return MR((u128)x, mod, inv); }
m64 addmod(m64 x, m64 y, m64 mod) {
return (x + y >= mod) ? x + y - mod: x + y;
}
m64 submod(m64 x, m64 y, m64 mod) {
return (i64)(x - y) < 0 ? x - y + mod : x - y;
}
m64 mulmod(m64 x, m64 y, m64 mod, m64 inv) {
return MR((u128)x * y, mod, inv);
}
m64 powmod(m64 x, int i, m64 mod, m64 inv, m64 r2) {
m64 ret = toM64(1, mod, inv, r2);
for (; i; i >>= 1) {
if (i & 1) ret = mulmod(ret, x, mod, inv);
x = mulmod(x, x, mod, inv);
}
return ret;
}
bool is_prime(u64 N) {
if (N < 2 || N % 6 % 4 != 1) return (N | 1) == 3;
int s = __builtin_ctzll(N - 1);
u64 d = (N - 1) >> s;
u64 as[] = {2, 325, 9375, 28178, 450775, 9780504, 1795265022};
m64 inv = calc_inv(N);
m64 r2 = calc_r2(N);
m64 e = toM64(1, N, inv, r2);
m64 f = toM64(N - 1, N, inv, r2);
for (int i = 0; i < 7; i++) {
m64 a = toM64(as[i], N, inv, r2);
m64 p = powmod(a, d, N, inv, r2);
if (a == 0 || p == e || p == f) continue;
for (int i = s - 1; p != f && i >= 0; --i) p = powmod(p, 2, N, inv, r2);
if (p != f) return false;
}
return true;
}
int main() {
int n; scanf("%d", &n);
for (int i = 0; i < n; i++) {
u64 x; scanf("%lu", &x);
if (is_prime(x)) {
printf("%d\n", 1);
}
else {
printf("%d\n", 0);
}
}
return 0;
}