#include #include #include #include #include #include using u64 = unsigned long long; using u128 = __uint128_t; static inline char loser(char w) { if (w == 'R') return 'S'; if (w == 'P') return 'R'; return 'P'; } struct Nat { bool inf; u64 v; static Nat from_rem(int rem) { if (rem < 0) return {false, 0}; if (rem >= 62) return {true, 0}; return {false, 1ULL << rem}; } bool is_zero() const { return !inf && v == 0; } Nat minus(u64 pa) const { if (inf) return *this; return {false, v - pa}; } }; static u128 subtree_leaves_u128(int rem) { if (rem <= 0) return 1; if (rem >= 127) return (u128)1 << 126; return (u128)1 << rem; } static bool k_too_large(u64 K, int nm1) { u128 cnt = subtree_leaves_u128(nm1); return (u128)K > cnt; } static std::vector expand(const std::vector &A, int N, const std::vector &cur, int depth, int side) { int t = N - 2 - depth; int p = A[t] - 1; std::vector ncur = cur; if (side == 0) { char w = ncur[p]; ncur.insert(ncur.begin() + p + 1, loser(w)); } else { char win = ncur[p]; ncur.insert(ncur.begin() + p, loser(win)); } return ncur; } static std::string kth_in_subtree(const std::vector &A, int N, const std::vector &cur, int depth, u64 k); static std::string kth_merge_nat(Nat na, u64 loA, Nat nb, u64 loB, u64 k, const std::function &getA, const std::function &getB) { if (na.is_zero()) return getB(loB + k); if (nb.is_zero()) return getA(loA + k); if (k == 0) { std::string sa = getA(loA); std::string sb = getB(loB); return std::min(sa, sb); } bool swap = false; if (na.inf != nb.inf) { if (na.inf && !nb.inf) swap = true; } else if (!na.inf && !nb.inf) { if (na.v > nb.v) swap = true; } if (swap) { return kth_merge_nat(nb, loB, na, loA, k, getB, getA); } u64 pa; if (na.inf) pa = (k + 1) / 2; else pa = std::min(na.v, (k + 1) / 2); u64 pb = k + 1 - pa; if (!nb.inf && pb > nb.v) { pb = nb.v; pa = k + 1 - pb; } std::string a_mid = getA(loA + pa - 1); std::string b_mid = getB(loB + pb - 1); if (a_mid < b_mid) return kth_merge_nat(na.minus(pa), loA + pa, nb, loB, k - pa, getA, getB); return kth_merge_nat(na, loA, nb.minus(pb), loB + pb, k - pb, getA, getB); } static std::string kth_in_subtree(const std::vector &A, int N, const std::vector &cur, int depth, u64 k) { if (depth == N - 1) return std::string(cur.begin(), cur.end()); auto L = expand(A, N, cur, depth, 0); auto R = expand(A, N, cur, depth, 1); int nd = depth + 1; int rem = N - 1 - nd; Nat nlen = Nat::from_rem(rem); auto getL = [&](u64 idx) { return kth_in_subtree(A, N, L, nd, idx); }; auto getR = [&](u64 idx) { return kth_in_subtree(A, N, R, nd, idx); }; return kth_merge_nat(nlen, 0, nlen, 0, k, getL, getR); } int main() { std::ios::sync_with_stdio(false); std::cin.tie(nullptr); int T; std::cin >> T; while (T--) { int N; u64 K; std::cin >> N >> K; std::vector A(N - 1); for (int i = 0; i < N - 1; ++i) std::cin >> A[i]; for (char fin : {'R', 'P', 'S'}) { if (k_too_large(K, N - 1)) { std::cout << -1 << '\n'; continue; } std::vector start{fin}; std::cout << kth_in_subtree(A, N, start, 0, K - 1) << '\n'; } } return 0; }