結果
問題 | No.3030 ミラー・ラビン素数判定法のテスト |
ユーザー | nonamae |
提出日時 | 2022-07-25 11:08:58 |
言語 | C++17 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 121 ms / 9,973 ms |
コード長 | 2,912 bytes |
コンパイル時間 | 1,964 ms |
コンパイル使用メモリ | 201,992 KB |
実行使用メモリ | 5,248 KB |
最終ジャッジ日時 | 2024-11-16 23:50:35 |
合計ジャッジ時間 | 3,000 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge2 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 1 ms
5,248 KB |
testcase_01 | AC | 2 ms
5,248 KB |
testcase_02 | AC | 2 ms
5,248 KB |
testcase_03 | AC | 2 ms
5,248 KB |
testcase_04 | AC | 68 ms
5,248 KB |
testcase_05 | AC | 83 ms
5,248 KB |
testcase_06 | AC | 64 ms
5,248 KB |
testcase_07 | AC | 63 ms
5,248 KB |
testcase_08 | AC | 64 ms
5,248 KB |
testcase_09 | AC | 121 ms
5,248 KB |
ソースコード
#include <bits/stdc++.h> using i32 = std::int32_t; using i64 = std::int64_t; using i128 = __int128_t; using u32 = std::uint32_t; using u64 = std::uint64_t; using u128 = __uint128_t; int jacobi(i64 a, u64 n) { u64 t; int j = 1; while (a) { if (a < 0) { a = -a; if ((n & 3) == 3) j = -j; } int s = __builtin_ctzll(a); a >>= s; if (((n & 7) == 3 || (n & 7) == 5) && (s & 1)) j = -j; if ((a & n & 3) == 3) j = -j; t = a, a = n, n = t; a %= n; if (((u64)a) > (n / 2)) a -= n; } return n == 1 ? j : 0; } int baillie_psw(u64 n) { { if (n == 2 || n == 3 || n == 5 || n == 7) return 1; if (n % 2 == 0 || n % 3 == 0 || n % 5 == 0 || n % 7 == 0) return 0; if (n < 121) return n > 1 ? 1 : 0; } { u64 d = (n - 1) << __builtin_clzll(n - 1); u64 t = 2; for (d <<= 1; d; d <<= 1) { t = u64((u128(t) * t) % n); if (d >> 63) { t <<= 1; if (t >= n) t -= n; } } if (t != 1) { u64 x = (n - 1) & -(n - 1); u64 rev = n - 1; for (x >>= 1; t != rev; x >>= 1) { if (x == 0) return 0; t = u64((u128(t) * t) % n); } } } { i64 D = 5; for (int i = 0; jacobi(D, n) != -1 && i < 64; ++i) { if (i == 32) { u32 k = round(sqrtl(n)); if (k * k == n) return 0; } if (i & 1) D -= 2; else D += 2; D = -D; } u64 Q = (D < 0) ? ((1 - D) / 4) % n : n - ((D - 1) / 4) % n; u64 k = (n + 1) << __builtin_clzll(n + 1); u64 u = 1; u64 v = 1; u64 Qn = Q; D %= (i64)n; D = (D < 0) ? n + D : D; for (k <<= 1; k; k <<= 1) { u = u64((u128(u) * v) % n); v = (n + u64((u128(v) * v) % n) - ((Qn * 2ull) % n)) % n; Qn = u64((u128(Qn) * Qn) % n); if (k >> 63) { u64 uu = u64((u128(u) + v) % n); if (uu & 1) uu += n; uu >>= 1; v = u64(((u128(D) * u) % n + v) % n); if (v & 1) v += n; v >>= 1; u = uu; Qn = u64((u128(Qn) * Q) % n); } } if (u == 0 || v == 0) return 1; u64 x = (n + 1) & ~n; for (x >>= 1; x; x >>= 1) { u = u64((u128(u) * v) % n); v = (n + u64((u128(v) * v) % n) - u64((u128(Qn) * 2) % n)) % n; if (v == 0) return 1; Qn = u64((u128(Qn) * Qn) % n); } } return 0; } int main() { int T; scanf("%d", &T); while (T--) { u64 x; scanf("%llu", &x); printf("%llu %d\n", x, baillie_psw(x)); } return 0; }