結果
| 問題 | No.2271 平方根の13桁精度近似計算 |
| コンテスト | |
| ユーザー |
lam6er
|
| 提出日時 | 2025-03-31 17:38:41 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
AC
|
| 実行時間 | 39 ms / 2,000 ms |
| コード長 | 2,783 bytes |
| コンパイル時間 | 160 ms |
| コンパイル使用メモリ | 82,100 KB |
| 実行使用メモリ | 54,620 KB |
| 最終ジャッジ日時 | 2025-03-31 17:39:43 |
| 合計ジャッジ時間 | 3,501 ms |
|
ジャッジサーバーID (参考情報) |
judge4 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 40 |
ソースコード
def main():
import sys
N, E = map(int, sys.stdin.read().split())
if E == 0:
print(0)
return
if N == 0:
print(0)
return
e = E
a = N % (5**e)
max_r = 2**29
min_r = -2**29
# Function to compute square roots modulo 5^e
def sqrt_mod(a, e):
if a == 0:
return [0]
k = 0
current_a = a
while current_a % 5 == 0:
k += 1
current_a = current_a // 5
if k % 2 != 0:
return None
m = k // 2
remaining_e = e - k
if remaining_e < 0:
return [0] # Only solution is x=0
if remaining_e == 0:
return [0]
y_sq_mod = current_a % (5**remaining_e)
# Find solutions to y^2 ≡ y_sq_mod mod 5
y_mod5 = []
for y in range(5):
if (y * y) % 5 == y_sq_mod % 5:
y_mod5.append(y)
if not y_mod5:
return None
# Hensel's lifting
solutions = y_mod5.copy()
for current_power in range(1, remaining_e):
new_solutions = []
mod = 5 ** (current_power + 1)
for sol in solutions:
val = sol * sol - y_sq_mod
if val % (5 ** (current_power + 1)) == 0:
new_solutions.append(sol)
continue
# Find t such that (sol + t * 5^current_power)^2 ≡ y_sq_mod mod 5^(current_power+1)
t_mod = (-val) // (5 ** current_power)
t_mod = (t_mod * pow(2 * sol, -1, 5)) % 5
new_sol = sol + t_mod * (5 ** current_power)
new_sol %= mod
new_solutions.append(new_sol)
solutions = list(set(new_solutions))
if not solutions:
return None
# Construct solutions
candidates = []
for y in solutions:
x = (5 ** m) * y
x_mod = x % (5 ** e)
candidates.append(x_mod)
candidates.append((-x_mod) % (5 ** e))
candidates = list(set(candidates))
return candidates
roots = sqrt_mod(a, e)
if roots is None:
print("NaN")
return
# Generate possible candidates
candidates = []
mod = 5 ** e
for r_mod in roots:
candidates.append(r_mod)
candidates.append(r_mod - mod)
candidates.append(r_mod + mod)
for k in [-2, -1, 2, 1]:
c = r_mod + k * mod
candidates.append(c)
for candidate in candidates:
if min_r <= candidate <= max_r:
# Verify if it's a solution (mod is already satisfied)
r = candidate
print(r)
return
print("NaN")
if __name__ == '__main__':
main()
lam6er