結果

問題 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
権限があれば一括ダウンロードができます

ソースコード

diff #

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()
0