use std::io::{self, Read}; const LIM: u128 = 1_000_000_000_000_000_000; const NONE: usize = usize::MAX; const CH: [u8; 3] = [b'P', b'R', b'S']; #[derive(Clone)] struct Node { l: usize, r: usize, cnt: [u128; 3], } struct Bit { n: usize, bit: Vec, } impl Bit { fn new(n: usize) -> Self { Self { n, bit: vec![0; n + 1], } } fn add(&mut self, mut i: usize, x: i64) { while i <= self.n { self.bit[i] += x; i += i & (!i + 1); } } fn kth(&self, mut k: i64) -> usize { let mut idx = 0usize; let mut w = 1usize; while (w << 1) <= self.n { w <<= 1; } while w > 0 { let ni = idx + w; if ni <= self.n && self.bit[ni] < k { idx = ni; k -= self.bit[ni]; } w >>= 1; } idx + 1 } } struct Scanner { buf: Vec, idx: usize, } impl Scanner { fn new() -> Self { let mut input = Vec::new(); io::stdin().read_to_end(&mut input).unwrap(); Self { buf: input, idx: 0 } } fn usize(&mut self) -> usize { while self.idx < self.buf.len() && self.buf[self.idx].is_ascii_whitespace() { self.idx += 1; } let mut res = 0usize; while self.idx < self.buf.len() && !self.buf[self.idx].is_ascii_whitespace() { res = res * 10 + (self.buf[self.idx] - b'0') as usize; self.idx += 1; } res } fn u128(&mut self) -> u128 { while self.idx < self.buf.len() && self.buf[self.idx].is_ascii_whitespace() { self.idx += 1; } let mut res = 0u128; while self.idx < self.buf.len() && !self.buf[self.idx].is_ascii_whitespace() { res = res * 10 + (self.buf[self.idx] - b'0') as u128; self.idx += 1; } res } } fn win(a: usize, b: usize) -> usize { if (a + 1) % 3 == b { a } else { b } } fn add_cap(a: u128, b: u128) -> u128 { (a + b).min(LIM) } fn mul_cap(a: u128, b: u128) -> u128 { (a * b).min(LIM) } fn cnt_node(nodes: &[Node], l: usize, r: usize) -> [u128; 3] { let mut res = [0u128; 3]; for x in 0..3 { let y = (x + 1) % 3; let v1 = mul_cap(nodes[l].cnt[x], nodes[r].cnt[y]); let v2 = mul_cap(nodes[l].cnt[y], nodes[r].cnt[x]); res[x] = add_cap(v1, v2); } res } fn left_weight(nodes: &[Node], r: usize, w: [u128; 3]) -> [u128; 3] { let mut res = [0u128; 3]; for lc in 0..3 { let mut now = 0u128; for rc in 0..3 { if lc == rc { continue; } let p = win(lc, rc); now = add_cap(now, mul_cap(nodes[r].cnt[rc], w[p])); } res[lc] = now; } res } fn right_weight(lc: usize, w: [u128; 3]) -> [u128; 3] { let mut res = [0u128; 3]; for rc in 0..3 { if lc != rc { res[rc] = w[win(lc, rc)]; } } res } enum Frame { Enter { v: usize, w: [u128; 3], k: u128, }, AfterLeft { v: usize, w: [u128; 3], }, AfterRight { lc: usize, }, } fn restore(nodes: &[Node], root: usize, target: usize, k: u128) -> Option { if nodes[root].cnt[target] < k { return None; } let mut ans = Vec::new(); let mut ret = (0usize, 0u128); let mut w0 = [0u128; 3]; w0[target] = 1; let mut st = vec![Frame::Enter { v: root, w: w0, k }]; while let Some(fr) = st.pop() { match fr { Frame::Enter { v, w, mut k } => { if nodes[v].l == NONE { for c in 0..3 { if k <= w[c] { ans.push(CH[c]); ret = (c, k); break; } k -= w[c]; } } else { let l = nodes[v].l; let r = nodes[v].r; let lw = left_weight(nodes, r, w); st.push(Frame::AfterLeft { v, w }); st.push(Frame::Enter { v: l, w: lw, k }); } } Frame::AfterLeft { v, w } => { let (lc, k2) = ret; let rw = right_weight(lc, w); st.push(Frame::AfterRight { lc }); st.push(Frame::Enter { v: nodes[v].r, w: rw, k: k2, }); } Frame::AfterRight { lc } => { let (rc, k2) = ret; ret = (win(lc, rc), k2); } } } Some(String::from_utf8(ans).unwrap()) } fn main() { let mut sc = Scanner::new(); let t = sc.usize(); let mut out = Vec::new(); for _ in 0..t { let n = sc.usize(); let k = sc.u128(); let mut a = vec![0usize; n - 1]; for i in 0..n - 1 { a[i] = sc.usize(); } let mut bit = Bit::new(n); let mut id = vec![0usize; n + 1]; let mut nodes = Vec::with_capacity(2 * n - 1); for i in 1..=n { bit.add(i, 1); id[i] = i - 1; nodes.push(Node { l: NONE, r: NONE, cnt: [1, 1, 1], }); } for x in a { let p = bit.kth(x as i64); let q = bit.kth(x as i64 + 1); let l = id[p]; let r = id[q]; let cnt = cnt_node(&nodes, l, r); let v = nodes.len(); nodes.push(Node { l, r, cnt }); id[p] = v; bit.add(q, -1); } let root = nodes.len() - 1; for target in [1usize, 0, 2] { match restore(&nodes, root, target, k) { Some(s) => out.push(s), None => out.push("-1".to_string()), } } } println!("{}", out.join("\n")); }