結果
| 問題 | No.3510 RPS Eliminations |
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2026-04-18 13:32:21 |
| 言語 | Rust (1.94.0 + proconio + num + itertools) |
| 結果 |
AC
|
| 実行時間 | 167 ms / 2,000 ms |
| コード長 | 6,149 bytes |
| 記録 | |
| コンパイル時間 | 1,101 ms |
| コンパイル使用メモリ | 205,844 KB |
| 実行使用メモリ | 48,920 KB |
| 最終ジャッジ日時 | 2026-04-18 13:32:28 |
| 合計ジャッジ時間 | 6,073 ms |
|
ジャッジサーバーID (参考情報) |
judge1_0 / judge2_1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 1 |
| other | AC * 28 |
ソースコード
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<i64>,
}
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<u8>,
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<String> {
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"));
}