結果
問題 | No.8030 ミラー・ラビン素数判定法のテスト |
ユーザー |
👑 |
提出日時 | 2024-12-18 20:04:14 |
言語 | PyPy3 (7.3.15) |
結果 |
AC
|
実行時間 | 1,156 ms / 9,973 ms |
コード長 | 3,700 bytes |
コンパイル時間 | 367 ms |
コンパイル使用メモリ | 82,016 KB |
実行使用メモリ | 86,244 KB |
最終ジャッジ日時 | 2024-12-18 20:04:22 |
合計ジャッジ時間 | 7,437 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge1 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
other | AC * 10 |
ソースコード
"""Python: Baillie-PSW素数判定法"""from typing import Optionalimport mathimport sysdef issq(n: int) -> bool:"""平方数判定"""if n < 0 or ((0x02030213 >> (n & 31)) & 1) == 0:return Falsereturn pow(math.isqrt(n), 2) == ndef kronecker_symbol(a: int, n: int) -> int:"""クロネッカー記号 https://en.wikipedia.org/wiki/Kronecker_symbol"""if n == 0:return int(a in (1, -1))j = 1if n < 0:n = -nif a < 0:j = -jif (n & 1) == 0:if (a & 1) == 0:return 0if ((a + 2) & 5) == 5 and ((n & -n).bit_length() & 1) == 0:j = -jn >>= (n & -n).bit_length() - 1if a < 0:a = -aif (n & 3) == 3:j = -jwhile a != 0:b = (a & -a).bit_length() - 1if ((n + 2) & 5) == 5 and (b & 1) != 0:j = -ja >>= bif (a & n & 3) == 3:j = -ja, n = n % a, aif n == 1:return jreturn 0def isprime_miller_base2(n: int) -> bool:"""基底2のミラーラビン擬素数判定"""#assert n > 2, 'value must be 3 or greater integer'#assert (n & 1) == 1, 'value must be odd integer'n1 = n - 1s = (n1 & -n1).bit_length() - 1d = n1 >> st = pow(2, d, n)if t in (1, n1):return Truefor _ in range(s - 1):t = pow(t, 2, n)if t == n1:return Truereturn Falsedef isprime_lucas(n: int) -> bool:"""強いリュカ擬素数判定 https://en.wikipedia.org/wiki/Lucas_pseudoprime#Strong_Lucas_pseudoprimes"""#assert n > 2, 'value must be 3 or greater integer'#assert (n & 1) == 1, 'value must be odd integer'd = lucas_dprobe(n)if d is None:return Falseq = ((1 - d) >> 2) % nk = n + 1j = (1 << k.bit_length()) >> 1k &= j - 1j >>= 1u, v, qn = 1, 1, qwhile k != 0:u = (u * v) % nv = (v * v - (qn + qn)) % nqn = (qn * qn) % nif (k & j) != 0:uu = u + vv = (d * u + v) % nu = uu + (n & -(uu & 1)) >> 1if u >= n:u -= nv = v + (n & -(v & 1)) >> 1qn = (qn * q) % nk ^= jj >>= 1if u == 0 or v == 0:return Truefor _ in range(((n + 1) & (~n)).bit_length() - 1):u = u * v % nv = (v * v - (qn + qn)) % nif v == 0:return Trueqn = (qn * qn) % nreturn Falsedef lucas_dprobe(n: int) -> Optional[int]:"""強いリュカ擬素数判定用の係数決定"""#assert n > 2, 'value must be 3 or greater integer'#assert (n & 1) == 1, 'value must be odd integer'i = 5while True:if i == n:i += 2d = i if (i & 3) == 1 else -ij = kronecker_symbol(d, n)if j == -1:return dif j == 0 and i < n:return Noneif i == 61 and issq(n):return Nonei += 2def isprime(n: int) -> bool:"""Baillie-PSW素数判定法 https://en.wikipedia.org/wiki/Baillie%E2%80%93PSW_primality_test"""if n < 2 or (n & 1) == 0:return n == 2return (isprime_miller_base2(n) and isprime_lucas(n))def __main__():"""yukicoder No.3030 ミラー・ラビン素数判定法のテスト https://yukicoder.me/problems/no/3030Mojacoder mizar/素数判定 (64bit) https://mojacoder.app/users/mizar/problems/isprime_64bit"""for _ in range(int(sys.stdin.readline().rstrip())):a = sys.stdin.readline().rstrip()print(a, int(isprime(int(a))))__main__()