#include #include #include #include #include using namespace std; const long long INF = 2e18; long long add(long long a, long long b) { return min(INF, a + b); } long long mul(long long a, long long b) { if (a == 0 || b == 0) return 0; if (INF / a < b) return INF; return a * b; } struct Vec { long long v[3]; Vec() { v[0] = v[1] = v[2] = 0; } Vec(long long r, long long p, long long s) { v[0] = r; v[1] = p; v[2] = s; } }; struct Mat { long long m[3][3]; Mat() { memset(m, 0, sizeof(m)); } Mat operator*(const Mat& o) const { Mat r; for (int i = 0; i < 3; ++i) { for (int k = 0; k < 3; ++k) { if (m[i][k]) { for (int j = 0; j < 3; ++j) { r.m[i][j] = add(r.m[i][j], mul(m[i][k], o.m[k][j])); } } } } return r; } }; Mat make_matrix(const Vec& A) { Mat M; M.m[0][0] = A.v[2]; M.m[0][2] = A.v[0]; M.m[1][1] = A.v[0]; M.m[1][0] = A.v[1]; M.m[2][2] = A.v[1]; M.m[2][1] = A.v[2]; return M; } Vec operator*(const Mat& m, const Vec& v) { Vec r; for (int i = 0; i < 3; ++i) { for (int j = 0; j < 3; ++j) { r.v[i] = add(r.v[i], mul(m.m[i][j], v.v[j])); } } return r; } struct BIT { int n; vector tree; BIT(int n) : n(n), tree(n + 1, 0) {} void add(int i, int delta) { for (; i <= n; i += i & -i) tree[i] += delta; } int find_kth(int k) { int idx = 0; for (int i = 20; i >= 0; i--) { int next_idx = idx + (1 << i); if (next_idx <= n && tree[next_idx] < k) { idx = next_idx; k -= tree[idx]; } } return idx + 1; } }; struct SegTree { int n; vector tree; SegTree() {} SegTree(int n) : n(n), tree(4 * n) { for (int i = 0; i < 4 * n; i++) { for (int j = 0; j < 3; j++) tree[i].m[j][j] = 1; } } void update(int node, int start, int end, int idx, const Mat& val) { if (start == end) { tree[node] = val; return; } int mid = (start + end) / 2; if (idx <= mid) update(2 * node, start, mid, idx, val); else update(2 * node + 1, mid + 1, end, idx, val); tree[node] = tree[2 * node] * tree[2 * node + 1]; } Mat query(int node, int start, int end, int l, int r) { if (r < start || end < l) { Mat id; for (int i = 0; i < 3; i++) id.m[i][i] = 1; return id; } if (l <= start && end <= r) return tree[node]; int mid = (start + end) / 2; return query(2 * node, start, mid, l, r) * query(2 * node + 1, mid + 1, end, l, r); } }; long long pow2[200005]; void solve() { int N; long long K; if (!(cin >> N >> K)) return; vector A(N - 1); for (int i = 0; i < N - 1; i++) cin >> A[i]; int V = 2 * N - 1; vector L(V, -1), R(V, -1), parent(V, -1); BIT bit(N); vector pos_to_node(N + 1); for (int i = 1; i <= N; i++) { bit.add(i, 1); pos_to_node[i] = i - 1; } for (int i = 0; i < N - 1; i++) { int p1 = bit.find_kth(A[i]); int p2 = bit.find_kth(A[i] + 1); int u = pos_to_node[p1]; int v = pos_to_node[p2]; int new_node = N + i; L[new_node] = u; R[new_node] = v; parent[u] = new_node; parent[v] = new_node; pos_to_node[p1] = new_node; bit.add(p2, -1); } int root = 2 * N - 2; vector sz(V, 0), heavy(V, -1); auto dfs_sz = [&](auto& self, int u) -> void { if (u < N) { sz[u] = 1; return; } self(self, L[u]); self(self, R[u]); sz[u] = sz[L[u]] + sz[R[u]]; if (sz[L[u]] >= sz[R[u]]) heavy[u] = L[u]; else heavy[u] = R[u]; }; dfs_sz(dfs_sz, root); vector head(V, -1), in(V, -1), tail(V, -1); int timer = 0; auto dfs_hld = [&](auto& self, int u, int h) -> void { head[u] = h; in[u] = timer++; if (heavy[u] != -1) { self(self, heavy[u], h); tail[u] = tail[heavy[u]]; } else { tail[u] = u; } if (L[u] != -1 && L[u] != heavy[u]) self(self, L[u], L[u]); if (R[u] != -1 && R[u] != heavy[u]) self(self, R[u], R[u]); }; dfs_hld(dfs_hld, root, root); SegTree initial_seg(V); vector initial_leaf_vec(V); for (int i = 0; i < N; i++) { initial_leaf_vec[i] = Vec(pow2[sz[i] - 1], pow2[sz[i] - 1], pow2[sz[i] - 1]); } for (int u = N; u < V; u++) { int light = (L[u] == heavy[u]) ? R[u] : L[u]; Vec light_val = Vec(pow2[sz[light] - 1], pow2[sz[light] - 1], pow2[sz[light] - 1]); initial_seg.update(1, 0, V - 1, in[u], make_matrix(light_val)); } SegTree seg; vector leaf_vec; auto get_path_W = [&](int h) -> Vec { int bottom = tail[h]; Mat m = seg.query(1, 0, V - 1, in[h], in[bottom] - 1); return m * leaf_vec[bottom]; }; auto update_leaf = [&](int leaf_idx, Vec new_W) { leaf_vec[leaf_idx] = new_W; int curr = leaf_idx; while (curr != -1) { int h = head[curr]; Vec top_W = get_path_W(h); int p = parent[h]; if (p != -1) { seg.update(1, 0, V - 1, in[p], make_matrix(top_W)); } curr = p; } }; for (int target : {0, 1, 2}) { seg = initial_seg; leaf_vec = initial_leaf_vec; long long K_rem = K; string ans = ""; bool possible = true; for (int i = 0; i < N; i++) { bool found = false; // 辞書順のため P, R, S の順に試す (P=1, R=0, S=2) for (int c : {1, 0, 2}) { Vec v(0, 0, 0); v.v[c] = 1; update_leaf(i, v); long long ways = get_path_W(head[root]).v[target]; if (K_rem <= ways) { ans += (c == 0 ? 'R' : (c == 1 ? 'P' : 'S')); found = true; break; } else { K_rem -= ways; } } if (!found) { possible = false; break; } } if (possible) cout << ans << "\n"; else cout << "-1\n"; } } int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); pow2[0] = 1; for (int i = 1; i <= 200000; i++) pow2[i] = min(INF, pow2[i - 1] * 2); int T; if (cin >> T) { while (T--) solve(); } return 0; }