結果
| 問題 |
No.8030 ミラー・ラビン素数判定法のテスト
|
| ユーザー |
nonamae
|
| 提出日時 | 2022-07-25 11:08:58 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 119 ms / 9,973 ms |
| コード長 | 2,912 bytes |
| コンパイル時間 | 1,833 ms |
| コンパイル使用メモリ | 197,188 KB |
| 最終ジャッジ日時 | 2025-01-30 13:58:08 |
|
ジャッジサーバーID (参考情報) |
judge3 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 10 |
コンパイルメッセージ
main.cpp: In function ‘int main()’:
main.cpp:103:26: warning: format ‘%llu’ expects argument of type ‘long long unsigned int*’, but argument 2 has type ‘u64*’ {aka ‘long unsigned int*’} [-Wformat=]
103 | u64 x; scanf("%llu", &x);
| ~~~^ ~~
| | |
| | u64* {aka long unsigned int*}
| long long unsigned int*
| %lu
main.cpp:104:20: warning: format ‘%llu’ expects argument of type ‘long long unsigned int’, but argument 2 has type ‘u64’ {aka ‘long unsigned int’} [-Wformat=]
104 | printf("%llu %d\n", x, baillie_psw(x));
| ~~~^ ~
| | |
| | u64 {aka long unsigned int}
| long long unsigned int
| %lu
main.cpp:101:17: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
101 | int T; scanf("%d", &T);
| ~~~~~^~~~~~~~~~
main.cpp:103:21: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
103 | u64 x; scanf("%llu", &x);
| ~~~~~^~~~~~~~~~~~
ソースコード
#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;
}
nonamae