Problem p03460 (C++)

Buggy submission (status: Memory Limit Exceeded):
#include <bits/stdc++.h>
using namespace std;

using VS = vector<string>;
using LL = long long;
using VI = vector<int>;
using VVI = vector<VI>;
using PII = pair<int, int>;
using PLL = pair<LL, LL>;
using VL = vector<LL>;
using VVL = vector<VL>;

#define ALL(a) begin((a)), end((a))
#define RALL(a) (a).rbegin(), (a).rend()
#define PB push_back
#define EB emplace_back
#define MP make_pair
#define SZ(a) int((a).size())
#define SORT(c) sort(ALL((c)))
#define RSORT(c) sort(RALL((c)))
#define UNIQ(c) (c).erase(unique(ALL((c))), end((c)))
#define FOR(i, s, e) for (int(i) = (s); (i) < (e); (i)++)
#define FORR(i, s, e) for (int(i) = (s); (i) > (e); (i)--)
#define debug(x) cout << #x << ": " << x << endl
const int INF = 1e9;
const LL LINF = 1e16;
const LL MOD = 1000000007;
const double PI = acos(-1.0);
int DX[8] = {0, 0, 1, -1, 1, 1, -1, -1};
int DY[8] = {1, -1, 0, 0, 1, -1, 1, -1};

/* -----  2018/01/21  Problem: ARC 089 B / Link:
 * http://arc089.contest.atcoder.jp/tasks/arc089_b  ----- */
/* ------問題------



-----問題ここまで----- */
/* -----解説等-----



----解説ここまで---- */

LL N, K;

LL ans = 0LL;

/* 2次元BIT 1-index. */
template <typename T> struct BIT2D {
  int H, W;
  vector<vector<T>> data; // mapで動的もできる
  BIT2D(int w, int h) {
    H = h;
    W = w;
    data = vector<vector<T>>(W + 1, vector<T>(H + 1, 0));
  } // 適当に

  void add(int a, int b, T val) { // (a,b)にvalを加算
    for (int x = a; x <= W; x += x & -x) {
      for (int y = b; y <= H; y += y & -y) {
        data[x][y] += val;
      }
    }
  }

  T _sum(int a, int b) { // [(1,1)~(a,b)]までの値の総和
    T ret = 0;
    for (int x = a; x > 0; x -= x & -x) {
      for (int y = b; y > 0; y -= y & -y) {
        ret += data[x][y];
      }
    }
    return ret;
  }
  T sum(int lx, int ly, int rx, int ry) { // [(lx,ly),(rx,ry)]までの値の総和
    return _sum(rx, ry) - _sum(lx - 1, ry) - _sum(rx, ly - 1) +
           _sum(lx - 1, ly - 1);
  }
};

template <typename T>
struct
    CumulativeSum2D { // 使うときは内部で1-indexになっているので普通に0-indexで使えばよい
  int H, W;
  vector<vector<T>> data;
  CumulativeSum2D(int H_, int W_) : data(H_ + 1, vector<T>(W_ + 1)) {
    H = H_, W = W_;
  };
  inline void add(int y, int x, T val) { // a[y][x](0≦p<N)をdata[y][x]に(0<p≦N)
    if (y > (int)data.size() || x > (int)data[0].size())
      return;
    data[y + 1][x + 1] += val;
  }                     //->buildする
  inline void build() { // data
    FOR(i, 0, H) FOR(j, 0, W) data[i + 1][j + 1] += data[i + 1][j];
    FOR(i, 0, H) FOR(j, 0, W) data[i + 1][j + 1] += data[i][j + 1];
  }
  inline void build2() { // かっこいい
    FOR(i, 0, H)
    FOR(j, 0, W) data[i + 1][j + 1] +=
        data[i + 1][j] + data[i][j + 1] - data[i][j];
  }
  inline T query(int y, int x) { // アクセス位置変更用
    if (y < H && x < W)
      return (data[y + 1][x + 1]);
    else if (x < W)
      return (data[H][x + 1]);
    else if (y < H)
      return (data[y + 1][W]);
    else
      return (data[H][W]);
  }
  inline T querysumhei(int sy, int sx, int ty,
                       int tx) { // 閉区間[(sy,sx),(ty,tx)]の和
    return query(ty, tx) - query(sy - 1, tx) - query(ty, sx - 1) +
           query(sy - 1, sx - 1);
  }
  inline T querysumhan(int sy, int sx, int ty,
                       int tx) { // 半開区間[(sy,sx),(ty,tx))の和
    return data[ty][tx] - data[sy][tx] - data[ty][sx] + data[sy][sx];
  }
};

void change(int x, int y, vector<PII> &a) {
  int ydiv = y / K;
  int xdiv = x / K;
  int X = ((xdiv + ydiv) % 2 == 0 ? (x % K) : (x % K));
  int Y = ((xdiv + ydiv) % 2 == 0 ? (y % K) : (y % K) + K);
  int ym = -1;
  if ((xdiv + ydiv) % 2 == 0) {
    ym = 1;
  }
  FOR(k, 0, 4) { // x , y
    a.push_back(PII(X + k * K, (k % 2 ? Y + K * ym : Y)));
  }
}
int main() {
  cin.tie(0);
  ios_base::sync_with_stdio(false);

  cin >> N >> K;

  VVI w(K, VI(2 * K));
  VVI b(K, VI(2 * K));
  VI x(N), y(N);

  CumulativeSum2D<LL> BB(5 * K, 5 * K);
  CumulativeSum2D<LL> WW(5 * K, 5 * K);
  string s;
  int wc = 0, bc = 0;
  FOR(i, 0, N) {
    cin >> x[i] >> y[i] >> s;
    if (s[0] == 'B') {
      vector<PII> a;
      change(x[i], y[i], a);
      FOR(j, 0, SZ(a)) { BB.add(a[j].second, a[j].first, 1); }
      // FOR(j, 0, SZ(a)) {
      //	B.add(a[j].first + 1, a[j].second + 1, 1);
      //	cout << "B DA" << endl;
      // }
      // cout << "N end" << endl;
    } else {
      vector<PII> a;
      change(x[i], y[i], a);

      FOR(j, 0, SZ(a)) { WW.add(a[j].second, a[j].first, 1); }
      // FOR(j, 0, SZ(a)) {
      //	W.add(a[j].first + 1, a[j].second + 1, 1);
      //	cout << "W DA" << endl;
      // }
      // cout << "N end" << endl;
    }
  }
  WW.build();
  BB.build();
  FOR(y, 0, K) { // y
    FOR(x, 0, 2 * K) {
      LL res = 0;
      res += BB.querysumhan(y, x, y + K, x + K);

      res += WW.querysumhan(y, x + K, y + K, x + 2 * K);
      ans = max(ans, res);
    }
  }
  // FOR(y, 1, K + 1) {// y
  //	FOR(x, 1, 2 * K + 1) {
  //		LL res = 0;
  //		debug(res);
  //		res += B.sum(x, y, x + K, y + K);
  //		res += W.sum(x + K + 1, y, x + K + K + 1, y + K);
  //		debug(res);
  //		ans = max(ans, res);
  //	}
  // }
  cout << ans << "\n";

  return 0;
}


Fixed submission:
#include <bits/stdc++.h>
using namespace std;

using VS = vector<string>;
using LL = long long;
using VI = vector<int>;
using VVI = vector<VI>;
using PII = pair<int, int>;
using PLL = pair<LL, LL>;
using VL = vector<LL>;
using VVL = vector<VL>;

#define ALL(a) begin((a)), end((a))
#define RALL(a) (a).rbegin(), (a).rend()
#define PB push_back
#define EB emplace_back
#define MP make_pair
#define SZ(a) int((a).size())
#define SORT(c) sort(ALL((c)))
#define RSORT(c) sort(RALL((c)))
#define UNIQ(c) (c).erase(unique(ALL((c))), end((c)))
#define FOR(i, s, e) for (int(i) = (s); (i) < (e); (i)++)
#define FORR(i, s, e) for (int(i) = (s); (i) > (e); (i)--)
#define debug(x) cout << #x << ": " << x << endl
const int INF = 1e9;
const LL LINF = 1e16;
const LL MOD = 1000000007;
const double PI = acos(-1.0);
int DX[8] = {0, 0, 1, -1, 1, 1, -1, -1};
int DY[8] = {1, -1, 0, 0, 1, -1, 1, -1};

/* -----  2018/01/21  Problem: ARC 089 B / Link:
 * http://arc089.contest.atcoder.jp/tasks/arc089_b  ----- */
/* ------問題------



-----問題ここまで----- */
/* -----解説等-----



----解説ここまで---- */

LL N, K;

LL ans = 0LL;

/* 2次元BIT 1-index. */
template <typename T> struct BIT2D {
  int H, W;
  vector<vector<T>> data; // mapで動的もできる
  BIT2D(int w, int h) {
    H = h;
    W = w;
    data = vector<vector<T>>(W + 1, vector<T>(H + 1, 0));
  } // 適当に

  void add(int a, int b, T val) { // (a,b)にvalを加算
    for (int x = a; x <= W; x += x & -x) {
      for (int y = b; y <= H; y += y & -y) {
        data[x][y] += val;
      }
    }
  }

  T _sum(int a, int b) { // [(1,1)~(a,b)]までの値の総和
    T ret = 0;
    for (int x = a; x > 0; x -= x & -x) {
      for (int y = b; y > 0; y -= y & -y) {
        ret += data[x][y];
      }
    }
    return ret;
  }
  T sum(int lx, int ly, int rx, int ry) { // [(lx,ly),(rx,ry)]までの値の総和
    return _sum(rx, ry) - _sum(lx - 1, ry) - _sum(rx, ly - 1) +
           _sum(lx - 1, ly - 1);
  }
};

template <typename T>
struct
    CumulativeSum2D { // 使うときは内部で1-indexになっているので普通に0-indexで使えばよい
  int H, W;
  vector<vector<T>> data;
  CumulativeSum2D(int H_, int W_) : data(H_ + 1, vector<T>(W_ + 1)) {
    H = H_, W = W_;
  };
  inline void add(int y, int x, T val) { // a[y][x](0≦p<N)をdata[y][x]に(0<p≦N)
    if (y > (int)data.size() || x > (int)data[0].size())
      return;
    data[y + 1][x + 1] += val;
  }                     //->buildする
  inline void build() { // data
    FOR(i, 0, H) FOR(j, 0, W) data[i + 1][j + 1] += data[i + 1][j];
    FOR(i, 0, H) FOR(j, 0, W) data[i + 1][j + 1] += data[i][j + 1];
  }
  inline void build2() { // かっこいい
    FOR(i, 0, H)
    FOR(j, 0, W) data[i + 1][j + 1] +=
        data[i + 1][j] + data[i][j + 1] - data[i][j];
  }
  inline T query(int y, int x) { // アクセス位置変更用
    if (y < H && x < W)
      return (data[y + 1][x + 1]);
    else if (x < W)
      return (data[H][x + 1]);
    else if (y < H)
      return (data[y + 1][W]);
    else
      return (data[H][W]);
  }
  inline T querysumhei(int sy, int sx, int ty,
                       int tx) { // 閉区間[(sy,sx),(ty,tx)]の和
    return query(ty, tx) - query(sy - 1, tx) - query(ty, sx - 1) +
           query(sy - 1, sx - 1);
  }
  inline T querysumhan(int sy, int sx, int ty,
                       int tx) { // 半開区間[(sy,sx),(ty,tx))の和
    return data[ty][tx] - data[sy][tx] - data[ty][sx] + data[sy][sx];
  }
};

void change(int x, int y, vector<PII> &a) {
  int ydiv = y / K;
  int xdiv = x / K;
  int X = ((xdiv + ydiv) % 2 == 0 ? (x % K) : (x % K));
  int Y = ((xdiv + ydiv) % 2 == 0 ? (y % K) : (y % K) + K);
  int ym = -1;
  if ((xdiv + ydiv) % 2 == 0) {
    ym = 1;
  }
  FOR(k, 0, 4) { // x , y
    a.push_back(PII(X + k * K, (k % 2 ? Y + K * ym : Y)));
  }
}
int main() {
  cin.tie(0);
  ios_base::sync_with_stdio(false);

  cin >> N >> K;

  VVI w(K, VI(2 * K));
  VVI b(K, VI(2 * K));
  VI x(N), y(N);

  CumulativeSum2D<LL> BB(2 * K, 4 * K);
  CumulativeSum2D<LL> WW(2 * K, 4 * K);
  string s;
  int wc = 0, bc = 0;
  FOR(i, 0, N) {
    cin >> x[i] >> y[i] >> s;
    if (s[0] == 'B') {
      vector<PII> a;
      change(x[i], y[i], a);
      FOR(j, 0, SZ(a)) { BB.add(a[j].second, a[j].first, 1); }
      // FOR(j, 0, SZ(a)) {
      //	B.add(a[j].first + 1, a[j].second + 1, 1);
      //	cout << "B DA" << endl;
      // }
      // cout << "N end" << endl;
    } else {
      vector<PII> a;
      change(x[i], y[i], a);

      FOR(j, 0, SZ(a)) { WW.add(a[j].second, a[j].first, 1); }
      // FOR(j, 0, SZ(a)) {
      //	W.add(a[j].first + 1, a[j].second + 1, 1);
      //	cout << "W DA" << endl;
      // }
      // cout << "N end" << endl;
    }
  }
  WW.build();
  BB.build();
  FOR(y, 0, K) { // y
    FOR(x, 0, 2 * K) {
      LL res = 0;
      res += BB.querysumhan(y, x, y + K, x + K);

      res += WW.querysumhan(y, x + K, y + K, x + 2 * K);
      ans = max(ans, res);
    }
  }
  // FOR(y, 1, K + 1) {// y
  //	FOR(x, 1, 2 * K + 1) {
  //		LL res = 0;
  //		debug(res);
  //		res += B.sum(x, y, x + K, y + K);
  //		res += W.sum(x + K + 1, y, x + K + K + 1, y + K);
  //		debug(res);
  //		ans = max(ans, res);
  //	}
  // }
  cout << ans << "\n";

  return 0;
}