結果

問題 No.3317 ワロングアンサーロングアンサーンスワロンガー
コンテスト
ユーザー elphe
提出日時 2025-10-25 11:18:27
言語 PyPy3
(7.3.15)
結果
AC  
実行時間 565 ms / 2,000 ms
コード長 3,325 bytes
コンパイル時間 255 ms
コンパイル使用メモリ 82,104 KB
実行使用メモリ 124,400 KB
最終ジャッジ日時 2025-11-01 09:59:03
合計ジャッジ時間 18,714 ms
ジャッジサーバーID
(参考情報)
judge3 / judge1
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 3
other AC * 63
権限があれば一括ダウンロードができます

ソースコード

diff #

import sys

def prepare(N: int, S: str):
    # return list of [cnt_other, cnt_a_or_w] cumulative of length N+1
    csum_count = [[0, 0] for _ in range(N + 1)]
    for i in range(N):
        if S[i] == 'w' or S[i] == 'a':
            csum_count[i + 1] = [csum_count[i][0], csum_count[i][1] + 1]
        else:
            csum_count[i + 1] = [csum_count[i][0] + 1, csum_count[i][1]]
    return csum_count

def solve(N: int, Q: int, S: str, T: list, X: list, csum_count):
    ans_chars = ['?'] * Q
    for i in range(Q):
        X[i] -= 1  # convert to 0-indexed
        if T[i] > 60:
            T[i] = 60

        # binary search for maximum l in [0, N] such that
        # csum_count[l][0] + csum_count[l][1] * (5 * (1 << T) - 4) <= X
        low, high = 0, N + 1
        Ti = T[i]
        # precompute multiplier
        mul = 5 * (1 << Ti) - 4
        while low + 1 < high:
            mid = (low + high) // 2
            cnt_a_w = csum_count[mid][1]
            cnt_other = csum_count[mid][0]
            # first condition in C++ avoids overflow: check cnt_a_w > (X - cnt_other) / mul
            # rearranged safely in Python not necessary, but keep same logic
            if cnt_a_w > (X[i] - cnt_other) // mul if mul != 0 else False:
                high = mid
            elif cnt_other + cnt_a_w * mul > X[i]:
                high = mid
            else:
                low = mid

        if csum_count[low][0] + csum_count[low][1] * mul == X[i]:
            # exact match => answer is S[low]
            ans_chars[i] = S[low]
        else:
            X[i] -= csum_count[low][0] + csum_count[low][1] * mul
            target = S  # will switch to literal strings when needed
            cursor = low
            Ti = T[i] - 1
            # loop while remaining X != 0 and Ti >= 0 (mirrors decrementing T in C++)
            while True:
                if X[i] == 0 or Ti < 0:
                    break
                ch = target[cursor]
                if ch == 'a':
                    target = "answer"
                elif ch == 'w':
                    target = "warong"
                else:
                    break  # abnormal; should not happen per problem constraints

                cursor = 0
                mul2 = 5 * (1 << Ti) - 4
                while True:
                    if X[i] == 0:
                        break
                    tch = target[cursor]
                    if tch != 'w' and tch != 'a':
                        X[i] -= 1
                        cursor += 1
                    elif X[i] < mul2:
                        break
                    else:
                        X[i] -= mul2
                        cursor += 1
                    # safety: if cursor reaches end of target, stop to avoid IndexError
                    if cursor >= len(target):
                        break
                Ti -= 1

            ans_chars[i] = target[cursor]

    return ''.join(ans_chars)

def main():
    data = sys.stdin.read().strip().split()
    it = iter(data)
    N = int(next(it))
    Q = int(next(it))
    S = next(it)
    T = [0] * Q
    X = [0] * Q
    for i in range(Q):
        T[i] = int(next(it))
        X[i] = int(next(it))

    csum = prepare(N, S)
    res = solve(N, Q, S, T, X, csum)
    sys.stdout.write(res + '\n')

if __name__ == "__main__":
    main()
0