H - Cut in Half Editorial by toam

小数を避ける方法

\(A\) を入力時点で \(2^{30}\) 倍して問題を解き,出力のときに求めた値を \(2^{30}\) で割った値を出力することで,出力以外はすべて 64bit 整数で扱うことができます.(理由:元の問題の答えは,\(N+K\lt 2^{30}\) よりある整数 \(n\) を用いて \(n/{2^{30}}\) と表されるため.)

def solve():
    N, K, X = map(int, input().split())
    A = list(map(int, input().split()))
    A = [i << 30 for i in A]

    def calc(mid):
        cnt = 0
        for i in A:
            c = 1
            while i > mid:
                c *= 2
                i //= 2
            cnt += c - 1
            cnt = min(cnt, K)
        return cnt

    ok, ng = 1 << 60, 0
    while abs(ok - ng) > 1:
        mid = (ok + ng) // 2
        if calc(mid) < K:
            ok = mid
        else:
            ng = mid

    B = []
    rem = K - calc(ok)

    for i in A:
        c = 1
        while i > ok:
            c *= 2
            i //= 2
        if i != ok:
            B.append((i, c))
        else:
            c1 = min(rem, c)
            c2 = c - c1
            B.append((i // 2, 2 * c1))
            B.append((i, c2))
            rem -= c1

    B.sort(reverse=True)
    for v, c in B:
        X -= c
        if X <= 0:
            print("{:.20f}".format(v / (1 << 30)))
            return


for _ in range(int(input())):
    solve()

posted:
last update: