use std::{convert::Infallible, io::Write, str::FromStr};
#[derive(Clone, Debug)]
struct Command {
vertical: bool,
index: u32,
color: u32,
}
impl FromStr for Command {
type Err = Infallible;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(match *s.split_ascii_whitespace().collect::<Box<[&str]>>() {
["R", row, color] => Command {
vertical: false,
index: row.parse::<u32>().unwrap() - 1,
color: color.parse::<u32>().unwrap() - 1,
},
["C", col, color] => Command {
vertical: true,
index: col.parse::<u32>().unwrap() - 1,
color: color.parse::<u32>().unwrap() - 1,
},
_ => panic!(),
})
}
}
fn main() {
let input = std::io::stdin().lines().next().unwrap().unwrap();
let mut input = input.split_ascii_whitespace().map(|l| l.parse().unwrap());
let height: u32 = input.next().unwrap();
let width = input.next().unwrap();
let colors = input.next().unwrap();
let instruction_count = input.next().unwrap() as usize;
drop(input);
let mut color_counts: Box<[u32]> =
unsafe { Box::new_zeroed_slice(colors as usize).assume_init() };
//stores indecies
let mut last_vert_paints: Box<[u32]> =
unsafe { Box::new_zeroed_slice(width as usize).assume_init() };
let mut last_hoiz_paints: Box<[u32]> =
unsafe { Box::new_zeroed_slice(height as usize).assume_init() };
let mut commands: Vec<Option<Command>> = Vec::with_capacity(instruction_count);
let mut stdout = std::io::stdout().lock();
for command in std::io::stdin()
.lines()
.take(instruction_count)
.map(|l| l.unwrap().parse::<Command>().unwrap())
{
let old_paint_idx = if command.vertical {
&mut last_vert_paints[command.index as usize]
} else {
&mut last_hoiz_paints[command.index as usize]
};
let real_old_paint_idx = old_paint_idx.saturating_sub(1);
let commands_to_check = commands
.iter()
.rev()
.take(commands.len() - real_old_paint_idx as usize)
.flatten();
let old_color_amount = if command.vertical {
color_counts[command.color as usize] += height;
height
- commands_to_check
.filter(|cmd| !cmd.vertical && cmd.color != command.color)
.inspect(|cmd| color_counts[cmd.color as usize] -= 1)
.count() as u32
} else {
color_counts[command.color as usize] += width;
width
- commands_to_check
.filter(|cmd| cmd.vertical && cmd.color != command.color)
.inspect(|cmd| color_counts[cmd.color as usize] -= 1)
.count() as u32
};
if *old_paint_idx != 0 {
color_counts[commands[real_old_paint_idx as usize]
.as_ref()
.unwrap()
.color as usize] -= old_color_amount;
commands[real_old_paint_idx as usize] = None;
}
commands.push(Some(command.clone()));
*old_paint_idx = commands.len() as u32;
}
for color in color_counts {
print!("{} ", color)
}
stdout.flush().unwrap();
}