Problem p01942 (C++) — buggy submission, verdict: Memory Limit Exceeded

#include <bits/stdc++.h>
using namespace std;
// BEGIN CUT HERE
template <typename T, typename E> struct SegmentTree {
  typedef function<T(T, T)> F;
  typedef function<T(T, E)> G;
  int n;
  F f;
  G g;
  T d1;
  E d0;
  vector<T> dat;
  SegmentTree(){};
  SegmentTree(int n_, F f, G g, T d1, vector<T> v = vector<T>()) {
    this->f = f;
    this->g = g;
    this->d1 = d1;
    init(n_);
    if (n_ == (int)v.size())
      build(n_, v);
  }
  void init(int n_) {
    n = 1;
    while (n < n_)
      n *= 2;
    dat.clear();
    dat.resize(2 * n - 1, d1);
  }
  void build(int n_, vector<T> v) {
    for (int i = 0; i < n_; i++)
      dat[i + n - 1] = v[i];
    for (int i = n - 2; i >= 0; i--)
      dat[i] = f(dat[i * 2 + 1], dat[i * 2 + 2]);
  }
  void update(int k, E a) {
    k += n - 1;
    dat[k] = g(dat[k], a);
    while (k > 0) {
      k = (k - 1) / 2;
      dat[k] = f(dat[k * 2 + 1], dat[k * 2 + 2]);
    }
  }
  T query(int a, int b, int k, int l, int r) {
    if (r <= a || b <= l)
      return d1;
    if (a <= l && r <= b)
      return dat[k];
    T vl = query(a, b, k * 2 + 1, l, (l + r) / 2);
    T vr = query(a, b, k * 2 + 2, (l + r) / 2, r);
    return f(vl, vr);
  }
  T query(int a, int b) { return query(a, b, 0, 0, n); }
};

template <typename T, typename E, typename R> struct SegmentTree2D {
  typedef function<T(void)> C;
  typedef function<R(R, R)> F;
  typedef function<void(T &, int, E)> G;
  typedef function<R(T &, int, int)> V;
  int n;
  F f;
  G g;
  V v;
  R d1;
  vector<T> dat;
  SegmentTree2D(int n_, C c, F f, G g, V v, R d1) {
    this->f = f;
    this->g = g;
    this->v = v;
    this->d1 = d1;
    init(n_, c);
  }
  void init(int n_, C c) {
    n = 1;
    while (n < n_)
      n *= 2;
    dat.clear();
    dat.resize(2 * n - 1);
    for (int i = 0; i < 2 * n - 1; i++)
      dat[i] = c();
  }
  void update(int x, int y, E e) {
    x += n - 1;
    g(dat[x], y, e);
    while (x > 0) {
      x = (x - 1) / 2;
      g(dat[x], y, e);
    }
  }
  R query(int a, int b, int c, int d, int k, int l, int r) {
    if (r <= a || b <= l)
      return d1;
    if (a <= l && r <= b)
      return v(dat[k], c, d);
    R vl = query(a, b, c, d, k * 2 + 1, l, (l + r) / 2);
    R vr = query(a, b, c, d, k * 2 + 2, (l + r) / 2, r);
    return f(vl, vr);
  }
  // [a,b) * [c,d)
  R query(int a, int b, int c, int d) { return query(a, b, c, d, 0, 0, n); }
};

// END CUT HERE
signed main() {
  cin.tie(0);
  ios::sync_with_stdio(0);
  int h, w, t, q;
  cin >> h >> w >> t >> q;
  using Int = short;
  typedef SegmentTree<Int, Int> T;
  SegmentTree2D<T, Int, int> beet(
      2048,
      [&]() {
        return T(
            2048, [](Int a, Int b) { return a + b; },
            [](Int a, Int b) { return a + b; }, 0);
      },
      [](int a, int b) { return a + b; },
      [](T &t, int k, Int e) { t.update(k, e); },
      [](T &t, int c, int d) { return t.query(c, d); }, 0);
  SegmentTree2D<T, Int, int> ushi(
      2048,
      [&]() {
        return T(
            2048, [](Int a, Int b) { return a + b; },
            [](Int a, Int b) { return a + b; }, 0);
      },
      [](int a, int b) { return a + b; },
      [](T &t, int k, Int e) { t.update(k, e); },
      [](T &t, int c, int d) { return t.query(c, d); }, 0);

  typedef pair<int, int> P;
  typedef pair<int, P> PP;
  queue<PP> qq;
  for (int i = 0; i < q; i++) {
    int a, c, x1, y1;
    cin >> a >> c >> x1 >> y1;
    while (!qq.empty() && qq.front().first <= a) {
      P p = qq.front().second;
      qq.pop();
      int x = p.first, y = p.second;
      assert(beet.query(x, x + 1, y, y + 1) == 1);
      beet.update(x, y, -1);
      assert(ushi.query(x, x + 1, y, y + 1) == 0);
      ushi.update(x, y, 1);
    }
    if (c == 0) {
      assert(beet.query(x1, x1 + 1, y1, y1 + 1) == 0);
      beet.update(x1, y1, 1);
      qq.push(PP(a + t, P(x1, y1)));
    }
    if (c == 1) {
      if (ushi.query(x1, x1 + 1, y1, y1 + 1) == 0)
        continue;
      ushi.update(x1, y1, -1);
    }
    if (c == 2) {
      int x2, y2;
      cin >> x2 >> y2;
      x2++;
      y2++;
      cout << ushi.query(x1, x2, y1, y2) << " " << beet.query(x1, x2, y1, y2)
           << endl;
    }
  }
  return 0;
}

Error: MLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
// BEGIN CUT HERE
template <typename T, typename E> struct SegmentTree {
  typedef function<T(T, T)> F;
  typedef function<T(T, E)> G;
  int n;
  F f;
  G g;
  T d1;
  E d0;
  vector<T> dat;
  SegmentTree(){};
  SegmentTree(int n_, F f, G g, T d1, vector<T> v = vector<T>()) {
    this->f = f;
    this->g = g;
    this->d1 = d1;
    init(n_);
    if (n_ == (int)v.size())
      build(n_, v);
  }
  void init(int n_) {
    n = 1;
    while (n < n_)
      n *= 2;
    dat.clear();
    dat.resize(2 * n - 1, d1);
  }
  void build(int n_, vector<T> v) {
    for (int i = 0; i < n_; i++)
      dat[i + n - 1] = v[i];
    for (int i = n - 2; i >= 0; i--)
      dat[i] = f(dat[i * 2 + 1], dat[i * 2 + 2]);
  }
  void update(int k, E a) {
    k += n - 1;
    dat[k] = g(dat[k], a);
    while (k > 0) {
      k = (k - 1) / 2;
      dat[k] = f(dat[k * 2 + 1], dat[k * 2 + 2]);
    }
  }
  T query(int a, int b, int k, int l, int r) {
    if (r <= a || b <= l)
      return d1;
    if (a <= l && r <= b)
      return dat[k];
    T vl = query(a, b, k * 2 + 1, l, (l + r) / 2);
    T vr = query(a, b, k * 2 + 2, (l + r) / 2, r);
    return f(vl, vr);
  }
  T query(int a, int b) { return query(a, b, 0, 0, n); }
};

template <typename T, typename E, typename R> struct SegmentTree2D {
  typedef function<T(void)> C;
  typedef function<R(R, R)> F;
  typedef function<void(T &, int, E)> G;
  typedef function<R(T &, int, int)> V;
  int n;
  F f;
  G g;
  V v;
  R d1;
  vector<T> dat;
  SegmentTree2D(int n_, C c, F f, G g, V v, R d1) {
    this->f = f;
    this->g = g;
    this->v = v;
    this->d1 = d1;
    init(n_, c);
  }
  void init(int n_, C c) {
    n = 1;
    while (n < n_)
      n *= 2;
    dat.clear();
    dat.resize(2 * n - 1);
    for (int i = 0; i < 2 * n - 1; i++)
      dat[i] = c();
  }
  void update(int x, int y, E e) {
    x += n - 1;
    g(dat[x], y, e);
    while (x > 0) {
      x = (x - 1) / 2;
      g(dat[x], y, e);
    }
  }
  R query(int a, int b, int c, int d, int k, int l, int r) {
    if (r <= a || b <= l)
      return d1;
    if (a <= l && r <= b)
      return v(dat[k], c, d);
    R vl = query(a, b, c, d, k * 2 + 1, l, (l + r) / 2);
    R vr = query(a, b, c, d, k * 2 + 2, (l + r) / 2, r);
    return f(vl, vr);
  }
  // [a,b) * [c,d)
  R query(int a, int b, int c, int d) { return query(a, b, c, d, 0, 0, n); }
};

// END CUT HERE
signed main() {
  cin.tie(0);
  ios::sync_with_stdio(0);
  int h, w, t, q;
  cin >> h >> w >> t >> q;
  using Int = short;
  typedef SegmentTree<Int, Int> T;
  SegmentTree2D<T, Int, Int> beet(
      h + 100,
      [&]() {
        return T(
            w + 100, [](Int a, Int b) { return a + b; },
            [](Int a, Int b) { return a + b; }, 0);
      },
      [](Int a, Int b) { return a + b; },
      [](T &t, int k, Int e) { t.update(k, e); },
      [](T &t, int c, int d) { return t.query(c, d); }, 0);
  SegmentTree2D<T, Int, Int> ushi(
      h + 100,
      [&]() {
        return T(
            w + 100, [](Int a, Int b) { return a + b; },
            [](Int a, Int b) { return a + b; }, 0);
      },
      [](Int a, Int b) { return a + b; },
      [](T &t, int k, Int e) { t.update(k, e); },
      [](T &t, int c, int d) { return t.query(c, d); }, 0);

  typedef pair<int, int> P;
  typedef pair<int, P> PP;
  queue<PP> qq;
  for (int i = 0; i < q; i++) {
    int a, c, x1, y1;
    cin >> a >> c >> x1 >> y1;
    while (!qq.empty() && qq.front().first <= a) {
      P p = qq.front().second;
      qq.pop();
      int x = p.first, y = p.second;
      assert(beet.query(x, x + 1, y, y + 1) == 1);
      beet.update(x, y, -1);
      assert(ushi.query(x, x + 1, y, y + 1) == 0);
      ushi.update(x, y, 1);
    }
    if (c == 0) {
      assert(beet.query(x1, x1 + 1, y1, y1 + 1) == 0);
      beet.update(x1, y1, 1);
      qq.push(PP(a + t, P(x1, y1)));
    }
    if (c == 1) {
      if (ushi.query(x1, x1 + 1, y1, y1 + 1) == 0)
        continue;
      ushi.update(x1, y1, -1);
    }
    if (c == 2) {
      int x2, y2;
      cin >> x2 >> y2;
      x2++;
      y2++;
      cout << ushi.query(x1, x2, y1, y2) << " " << beet.query(x1, x2, y1, y2)
           << endl;
    }
  }
  return 0;
}