use proconio::input; fn main() { let ans = Solver::new().solve(); println!("{}", ans); } struct Solver { n: usize, s: String, k: u64, all: Vec, } impl Solver { fn new() -> Self { input! { n: usize, k: u64, s: String, } Self { n, s, k, all: vec![], } } fn solve(&mut self) -> String { // let mut cur = "".to_string(); // self.dfs(0, &mut cur); // self.all.sort(); // return self.all[(self.k - 1) as usize].clone(); let mut ans = "".to_string(); let dp = self.count(); let mut pos = 0; let mut res = self.k; while pos < self.n { for len in 1..=2 { if !self.to_num_ok(pos, len) { continue; } let cnt = dp[pos + len]; if cnt < res { res -= cnt; continue; } ans.push( self.s[pos..pos + len] .parse::() .map(|x| (b'a' + x - 1) as char) .unwrap(), ); pos += len; break; } } ans } fn count(&self) -> Vec { let mut dp = vec![0u64; self.n + 1]; dp[self.n] = 1; for i in (0..self.n).rev() { for len in 1..=2 { if self.to_num_ok(i, len) { dp[i] = dp[i].saturating_add(dp[i + len]); } } } dp } fn to_num_ok(&self, i: usize, len: usize) -> bool { if i + len > self.n { return false; } let sub = &self.s[i..i + len]; sub.parse::().is_ok_and(|x| (1..=26).contains(&x)) } fn dfs(&mut self, pos: usize, cur: &mut String) { if pos == self.n { self.all.push(cur.clone()); return; } for len in 1..=2 { if self.to_num_ok(pos, len) { cur.push( self.s[pos..pos + len] .parse::() .map(|x| (b'a' + x - 1) as char) .unwrap(), ); self.dfs(pos + len, cur); cur.pop(); } } } }