Problem p03458 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;
#define rep(i, l, r) for (int i = (l); i < (r); ++i)
typedef long long ll;
template <class T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}

void set_square(int x, int y, int k, vector<vector<int>> &imos) {
  if (x < 0 || y < 0)
    return;
  imos[max(0, x - k + 1)][max(0, y - k + 1)] += 1;
  imos[max(0, x - k + 1)][min(y + 1, 2 * k)] -= 1;
  imos[min(x + 1, 2 * k)][max(0, y - k + 1)] -= 1;
  imos[min(x + 1, 2 * k)][min(y + 1, 2 * k)] += 1;
}

void set_imos(int x, int y, int k, vector<vector<int>> &imos) {
  set_square(x, y, k, imos);
  set_square(x + k, y - k, k, imos);
  set_square(x - k, y - k, k, imos);
  set_square(x + k, y + k, k, imos);
  set_square(x - k, y + k, k, imos);
  set_square(x, y + 2 * k, k, imos);
}

int main() {
  int n, k;
  cin >> n >> k;
  // 入力を受け取り、扱いやすいように希望を同値変形して座標を圧縮する
  // 具体的には全ての希望を、「(x,y)∈[0,2k)*[0,2k)を黒に塗りたいな」という希望に同値変形する
  vector<int> x(n), y(n);
  rep(i, 0, n) {
    cin >> x[i] >> y[i];
    char c;
    cin >> c;
    if (c == 'W')
      x[i] += k;
    x[i] %= 2 * k;
    y[i] %= 2 * k;
  }

  // 市松模様は[0,2k)*[0,2k)のどこを黒い部分の左下にするかという情報で一意に定まる（全単射）ので、そのように表す
  // imos[i][j] :=
  // (i,j)が黒い部分の左下になるような市松模様を塗った時に叶えられる希望の数
  vector<vector<int>> imos(2 * k + 5, vector<int>(2 * k + 5, 0));
  rep(i, 0, n) {
    // (x[i],y[i])を黒に塗れるような市松模様(X, Y)について、最後に累積した時に
    // imos[X][Y]+=1 になるように重みを加算する
    set_imos(x[i], y[i], k, imos);
  }

  // 左→右へ累積
  rep(i, 0, 2 * k) rep(j, 1, 2 * k) imos[i][j] += imos[i][j - 1];
  // （問題文の画像で）下→上へ累積
  rep(j, 0, 2 * k) rep(i, 1, 2 * k) imos[i][j] += imos[i - 1][j];

  // 最大値の検索
  int ans = 0;
  rep(i, 0, 2 * k) rep(j, 0, 2 * k) chmax(ans, imos[i][j]);

  cout << ans << '\n';
  return 0;
}


Fixed submission:
#include <bits/stdc++.h>
using namespace std;
#define rep(i, l, r) for (int i = (l); i < (r); ++i)
typedef long long ll;
template <class T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}

void set_square(int x, int y, int k, vector<vector<int>> &imos) {
  if (x < 0 || y < 0 || x >= 3 * k - 1 || y >= 3 * k - 1)
    return;
  imos[max(0, x - k + 1)][max(0, y - k + 1)] += 1;
  imos[max(0, x - k + 1)][min(y + 1, 2 * k)] -= 1;
  imos[min(x + 1, 2 * k)][max(0, y - k + 1)] -= 1;
  imos[min(x + 1, 2 * k)][min(y + 1, 2 * k)] += 1;
}

void set_imos(int x, int y, int k, vector<vector<int>> &imos) {
  set_square(x, y, k, imos);
  set_square(x + k, y - k, k, imos);
  set_square(x - k, y - k, k, imos);
  set_square(x + k, y + k, k, imos);
  set_square(x - k, y + k, k, imos);
  set_square(x, y + 2 * k, k, imos);
}

int main() {
  int n, k;
  cin >> n >> k;
  // 入力を受け取り、扱いやすいように希望を同値変形して座標を圧縮する
  // 具体的には全ての希望を、「(x,y)∈[0,2k)*[0,2k)を黒に塗りたいな」という希望に同値変形する
  vector<int> x(n), y(n);
  rep(i, 0, n) {
    cin >> x[i] >> y[i];
    char c;
    cin >> c;
    if (c == 'W')
      x[i] += k;
    x[i] %= 2 * k;
    y[i] %= 2 * k;
  }

  // 市松模様は[0,2k)*[0,2k)のどこを黒い部分の左下にするかという情報で一意に定まる（全単射）ので、そのように表す
  // imos[i][j] :=
  // (i,j)が黒い部分の左下になるような市松模様を塗った時に叶えられる希望の数
  vector<vector<int>> imos(2 * k + 5, vector<int>(2 * k + 5, 0));
  rep(i, 0, n) {
    // (x[i],y[i])を黒に塗れるような市松模様(X, Y)について、最後に累積した時に
    // imos[X][Y]+=1 になるように重みを加算する
    set_imos(x[i], y[i], k, imos);
  }

  // 左→右へ累積
  rep(i, 0, 2 * k) rep(j, 1, 2 * k) imos[i][j] += imos[i][j - 1];
  // （問題文の画像で）下→上へ累積
  rep(j, 0, 2 * k) rep(i, 1, 2 * k) imos[i][j] += imos[i - 1][j];

  // 最大値の検索
  int ans = 0;
  rep(i, 0, 2 * k) rep(j, 0, 2 * k) chmax(ans, imos[i][j]);

  cout << ans << '\n';
  return 0;
}