use proconio::input; fn prepare(n: usize, s: &Vec) -> Vec<[i32; 2]> { let mut csum = vec![[0i32, 0i32]; n + 1]; for i in 0..n { if s[i] == b'w' || s[i] == b'a' { csum[i + 1] = [csum[i][0], csum[i][1] + 1]; } else { csum[i + 1] = [csum[i][0] + 1, csum[i][1]]; } } csum } fn solve( n: usize, q: usize, s: &Vec, mut t: Vec, mut x: Vec, csum: &Vec<[i32; 2]>, ) -> String { let mut ans = vec![b'?'; q]; for i in 0..q { x[i] -= 1; // 1-indexed -> 0-indexed if t[i] > 60 { t[i] = 60; } let ti = t[i] as u32; // mul as i128 to avoid intermediate overflow let mul = (5i128) * ((1i128) << ti) - 4i128; // binary search for maximum l in [0, n] satisfying // csum[l][0] + csum[l][1] * mul <= x[i] let mut l: isize = 0; let mut r: isize = (n as isize) + 1; while l + 1 < r { let mid = ((l + r) / 2) as usize; let cnt_a_w = csum[mid][1] as i128; let cnt_other = csum[mid][0] as i128; // first condition: cnt_a_w > (x - cnt_other) / mul let cond1 = if mul != 0 { // note: use floor div for negative safety though x - cnt_other is non-negative in valid ranges cnt_a_w > ((x[i] as i128 - cnt_other) / mul) } else { false }; if cond1 { r = mid as isize; } else if cnt_other + cnt_a_w * mul > x[i] as i128 { r = mid as isize; } else { l = mid as isize; } } let l_usize = l as usize; let total_at_l = (csum[l_usize][0] as i128) + (csum[l_usize][1] as i128) * mul; if total_at_l == x[i] as i128 { // exact match // S[l] // safe because l in [0..=n-1] when match exists; but if l == n then S[n] would be OOB. // In C++ code it assumed valid; we mirror that assumption. ans[i] = s[l_usize]; } else { x[i] -= total_at_l as i64; // target starts as S, but switch to literal strings when encountering a/w let mut target_bytes: &[u8] = s; let mut cursor: usize = l_usize; let mut remaining_t = t[i] - 1; while x[i] != 0 && remaining_t >= 0 { // current character at cursor in target_bytes let ch = *target_bytes.get(cursor).unwrap_or(&b'?'); if ch == b'a' { target_bytes = b"answer"; } else if ch == b'w' { target_bytes = b"warong"; } else { // abnormal; break break; } cursor = 0; let mul2 = (5i128) * ((1i128) << (remaining_t as u32)) - 4i128; // iterate over target_bytes while x[i] != 0 { let tch = *target_bytes.get(cursor).unwrap_or(&b'?'); if tch != b'w' && tch != b'a' { x[i] -= 1; cursor += 1; } else if (x[i] as i128) < mul2 { break; } else { x[i] -= mul2 as i64; cursor += 1; } if cursor >= target_bytes.len() { break; } } remaining_t -= 1; } ans[i] = *target_bytes.get(cursor).unwrap_or(&b'?'); } } // convert to String String::from_utf8(ans).unwrap_or_default() } fn main() { input! { n: usize, q: usize, s_raw: String, queries: [(i64, i64); q], } let s_bytes: Vec = s_raw.into_bytes(); let mut t = vec![0i64; q]; let mut x = vec![0i64; q]; for i in 0..q { t[i] = queries[i].0; x[i] = queries[i].1; } let csum = prepare(n, &s_bytes); let ans = solve(n, q, &s_bytes, t, x, &csum); println!("{}", ans); }