https://atcoder.jp/contests/abc314/tasks/abc314_d
1が続く間は、変えた位置を記録しておきます。2か3が出てくるとそれをリセットします。最後に、全体を大文字か小文字にしますが、記録していた位置だけは大文字、小文字を変えずにそのままにします。
Rustのバージョンが大幅にアップしましたね。手元と同じです。
// LOWER #![allow(non_snake_case)] use std::collections::HashSet; //////////////////// library //////////////////// fn read<T: std::str::FromStr>() -> T { let mut line = String::new(); std::io::stdin().read_line(&mut line).ok(); line.trim().parse().ok().unwrap() } fn read_vec<T: std::str::FromStr>() -> Vec<T> { read::<String>().split_whitespace() .map(|e| e.parse().ok().unwrap()).collect() } //////////////////// Query //////////////////// struct Query { t: i32, x: usize, c: char } impl Query { fn operate(&self, cs: &mut VecChar) { match *self { Query { t: 1, x, c } => cs.change(x-1, c), Query { t, x: _, c: _ } => cs.turn(t) } } fn read() -> Query { let v: Vec<String> = read_vec(); let t: i32 = v[0].parse().unwrap(); let x: usize = v[1].parse().unwrap(); let c = v[2].chars().next().unwrap(); Query { t, x, c } } } //////////////////// VecChar //////////////////// struct VecChar { cs: Vec<char>, prev_t: i32, change_indices: HashSet<usize> } impl VecChar { fn new(S: String) -> VecChar { let cs: Vec<char> = S.chars().collect(); let change_indices: HashSet<usize> = HashSet::new(); VecChar { cs, prev_t: 1, change_indices } } fn change(&mut self, x: usize, c: char) { self.cs[x] = c; self.change_indices.insert(x); } fn turn(&mut self, t: i32) { self.prev_t = t; self.change_indices.clear() } fn convert(&self, i: usize) -> char { if self.change_indices.contains(&i) { self.cs[i] } else if self.prev_t == 2 { self.cs[i].to_ascii_lowercase() } else if self.prev_t == 3 { self.cs[i].to_ascii_uppercase() } else { self.cs[i] } } fn to_string(&self) -> String { (0..self.cs.len()).map(|i| self.convert(i)).collect::<String>() } } //////////////////// process //////////////////// fn read_input() -> (String, usize) { let _N: usize = read(); let S = read(); let Q = read(); (S, Q) } fn f(S: String, Q: usize) -> String { let mut cs = VecChar::new(S); for _ in 0..Q { let query = Query::read(); query.operate(&mut cs) } cs.to_string() } //////////////////// main //////////////////// fn main() { let (S, Q) = read_input(); println!("{}", f(S, Q)) }