結果

問題 No.3510 RPS Eliminations
コンテスト
ユーザー Naru820
提出日時 2026-04-01 10:56:11
言語 PyPy3
(7.3.17)
コンパイル:
pypy3 -mpy_compile _filename_
実行:
pypy3 _filename_
結果
TLE  
(最新)
AC  
(最初)
実行時間 -
コード長 3,511 bytes
記録
記録タグの例:
初AC ショートコード 純ショートコード 純主流ショートコード 最速実行時間
コンパイル時間 327 ms
コンパイル使用メモリ 85,120 KB
実行使用メモリ 123,904 KB
最終ジャッジ日時 2026-04-17 20:02:58
合計ジャッジ時間 22,312 ms
ジャッジサーバーID
(参考情報)
judge2_0 / judge1_1
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample -- * 1
other AC * 20 TLE * 1 -- * 7
権限があれば一括ダウンロードができます

ソースコード

diff #
raw source code

import sys

INFL = 3 * 10**18 + 100


class BIT:
    def __init__(self, n):
        self.size = n
        self.tree = [0] * (n + 1)

    def sum(self, i):
        s = 0
        while i > 0:
            s += self.tree[i]
            i -= i & -i
        return s

    def add(self, i, x):
        while i <= self.size:
            self.tree[i] += x
            i += i & -i

    def kth(self, k):
        idx = 0
        step = 1
        while (step << 1) <= self.size:
            step <<= 1
        d = step
        while d > 0:
            nxt = idx + d
            if nxt <= self.size and self.tree[nxt] < k:
                idx = nxt
                k -= self.tree[nxt]
            d >>= 1
        return idx + 1


def solve():
    input = sys.stdin.readline
    T = int(input())
    PRS = "PRS"

    def safe_pow2(n):
        if n > 60:
            return INFL
        return 1 << n

    def janken_win(a, b):
        if a == b:
            return -1
        if (a - b + 3) % 3 == 2:
            return a
        return b

    sys.setrecursionlimit(1_000_000)

    for _ in range(T):
        N, K = map(int, input().split())
        A = list(map(int, input().split()))

        if safe_pow2(N - 1) < K:
            print("-1")
            print("-1")
            print("-1")
            continue

        bit = BIT(N)
        for i in range(1, N + 1):
            bit.add(i, 1)

        idx = list(range(N))
        par = [-1] * (N * 2 - 1)
        subtree = [0] * (N * 2 - 1)
        for i in range(N):
            subtree[i] = 1
        child = [(-1, -1) for _ in range(N * 2 - 1)]

        for i in range(N - 1):
            # seg.max_right(0, x < A[i])     -> A[i] 番目の生きている位置
            # seg.max_right(0, x < A[i] + 1) -> A[i]+1 番目の生きている位置
            # BIT.kth は 1-indexed で返すので -1 して 0-indexed に直す
            l = bit.kth(A[i]) - 1
            r = bit.kth(A[i] + 1) - 1

            child[i + N] = (idx[l], idx[r])
            subtree[i + N] = subtree[idx[l]] + subtree[idx[r]]
            par[idx[l]] = i + N
            par[idx[r]] = i + N

            idx[l] = i + N
            idx[r] = -1
            bit.add(r + 1, -1)  # r を削除

        def dfs(v, cnt, k_ref, res):
            k = k_ref[0]
            if child[v][0] == -1:
                for i in range(3):
                    if k <= cnt[i]:
                        res[v] = PRS[i]
                        k_ref[0] = k
                        return i
                    k -= cnt[i]
                raise AssertionError
            else:
                lch, rch = child[v]

                cntL = [0, 0, 0]
                mul = safe_pow2(subtree[rch] - 1)
                for i in range(3):
                    cntL[i] = min((cnt[i] + cnt[(i + 2) % 3]) * mul, INFL)

                l = dfs(lch, cntL, k_ref, res)

                cntR = [0, 0, 0]
                for i in range(3):
                    if i == l:
                        cntR[i] = 0
                    else:
                        cntR[i] = cnt[janken_win(l, i)]

                r = dfs(rch, cntR, k_ref, res)
                return janken_win(l, r)

        ans = [""] * N

        k_ref = [K]
        dfs(N * 2 - 2, [0, 1, 0], k_ref, ans)
        print("".join(ans))

        k_ref = [K]
        dfs(N * 2 - 2, [1, 0, 0], k_ref, ans)
        print("".join(ans))

        k_ref = [K]
        dfs(N * 2 - 2, [0, 0, 1], k_ref, ans)
        print("".join(ans))


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