#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdint.h>
#include <unordered_map>
uint64_t *colors;
size_t width;
size_t height;
size_t color_count;
size_t get_uuid(int32_t rc, size_t n) {
return ((size_t)rc << 32) | n;
}
struct DrawData {
int32_t color;
size_t covered;
};
std::unordered_map<size_t, DrawData> row_ops;
std::unordered_map<size_t, DrawData> col_ops;
std::unordered_map<size_t, std::unordered_set<size_t>> ops_covered;
void insert_op(int rc, size_t n, int color) {
if (rc == 'R') {
row_ops[get_uuid(rc, n)] = {color, width};
} else {
col_ops[get_uuid(rc, n)] = {color, height};
}
}
void draw_line(int rc, size_t n, int color) {
if (row_ops.size() == 0 and col_ops.size() == 0) {
insert_op(rc, n, color);
return;
}
bool same_line_found = false;
if (rc == 'R') {
const auto it = row_ops.find(get_uuid(rc, n));
if (it != row_ops.end()) {
it->second.covered = 0;
}
for (auto &c : col_ops) {
c.second.covered--;
ops_covered[get_uuid(rc, n)].push_back(c.first);
}
} else {
const auto it = col_ops.find(get_uuid(rc, n));
if (it != col_ops.end()) {
it->second.covered = 0;
same_line_found = true;
}
for (auto &r : row_ops) {
const auto it2 = ops_covered.find(it.first);
ops_covered[get_uuid(rc, n)].insert(c.first);
if (it2 != ops_covered.end()) {
if (it2->second.find(r.first) == it2->second.end()) {
r.second.covered--;
} else {
it2->second.erase(it2->second.find(r.first));
}
} else {
r.second.covered--;
}
}
}
insert_op(rc, n, color);
}
int main(void) {
char *input = (char *)malloc(1024*1024*8);
const size_t len = read(0, input, 1024*1024*8);
size_t idx = 0;
size_t next_space = strchr(input, ' ') - input;
input[next_space] = '\0';
height = atoi(input);
idx += next_space + 1;
next_space = strchr((input + idx), ' ') - (input + idx);
(input + idx)[next_space] = '\0';
width = atoi((input + idx));
idx += next_space + 1;
next_space = strchr((input + idx), ' ') - (input + idx);
(input + idx)[next_space] = '\0';
color_count = atoi((input + idx));
idx += next_space + 1;
next_space = strchr((input + idx), '\n') - (input + idx);
(input + idx)[next_space] = '\0';
size_t operations = atoi((input + idx));
idx += next_space + 1;
colors = (uint64_t *)malloc((color_count + 1) * sizeof(uint64_t));
row_ops.reserve(operations);
col_ops.reserve(operations);
for (size_t i = 0; i < color_count + 1; i++) {
colors[i] = 0;
}
for (size_t i = 0; i < operations; i++) {
int rc = (input + idx)[0];
idx += 2;
next_space = strchr((input + idx), ' ') - (input + idx);
(input + idx)[next_space] = '\0';
size_t n = atoi((input + idx));
idx += next_space + 1;
if (i == operations - 1) {
next_space = len - ((input + idx) - input) - 1;
} else {
next_space = strchr((input + idx), '\n') - (input + idx);
}
(input + idx)[next_space] = '\0';
size_t color = atoi((input + idx));
idx += next_space + 1;
draw_line(rc, n, color);
}
for (auto &r : row_ops) {
colors[r.second.color] += r.second.covered;
}
for (auto &r : col_ops) {
colors[r.second.color] += r.second.covered;
}
for (size_t i = 1; i < color_count + 1; i++) {
printf("%lu ", colors[i]);
}
free(input);
free(colors);
}