Problem p00541 (C++)

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

const int N = 4005;

int n, m, P, L;
int a[N][N];
int l[N][N], r[N][N], u[N][N], d[N][N];
long long ans;

int T[N];
void upd(int x, int v) {
  for (; x <= n; x += x & -x)
    T[x] += v;
}
int get(int x) {
  int res = 0;
  for (; x > 0; x -= x & -x)
    res += T[x];
  return res;
}

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cin >> n >> m >> L >> P;
  for (int i = 1; i <= P; ++i) {
    int u, v;
    cin >> u >> v;
    a[u][v] = 1;
  }

  for (int i = 1; i <= n; ++i) {
    l[i][0] = 0;
    r[i][m + 1] = m + 1;
    for (int j = 1; j <= m; ++j)
      l[i][j] = (a[i][j] ? j : l[i][j - 1]);
    for (int j = m; j >= 1; --j)
      r[i][j] = (a[i][j] ? j : r[i][j + 1]);
  }
  for (int j = 1; j <= m; ++j) {
    u[0][j] = 0;
    d[n + 1][j] = n + 1;
    for (int i = 1; i <= n; ++i)
      u[i][j] = (a[i][j] ? i : u[i - 1][j]);
    for (int i = n; i >= 1; --i)
      d[i][j] = (a[i][j] ? i : d[i + 1][j]);
  }
  for (int i = 1; i <= n; ++i)
    for (int j = 1; j <= m; ++j) {
      d[i][j] = min(d[i][j] - i, r[i][j] - j) - 1;
      u[i][j] = min(i - u[i][j], j - l[i][j]) - 1;
      // cerr << i << ' ' << j << ' ' << d[i][j] << ' ' << u[i][j] << endl;
    }

  for (int h = 1 - m; h <= n - 1; ++h) {
    // cerr << h << endl;
    vector<int> Z;
    vector<pair<int, int>> v;
    for (int i = n; i >= 1; --i) {
      int j = i - h;
      if (j < 1 || j > m)
        continue;
      v.push_back(make_pair(i - u[i][j], i));
    }
    sort(v.begin(), v.end());
    for (int i = 0; i <= n; ++i)
      T[i] = 0;

    int ptr = 0;
    for (int i = 1; i <= n; ++i) {
      int j = i - h;
      if (j < 1 || j > m)
        continue;
      // cerr << h << " -> " << i << ' ' << j << endl;
      while (ptr < (int)v.size() && v[ptr].first <= i) {
        int k = v[ptr].second; // cerr << k << ' ' << v[ptr].first << endl;
        upd(k, 1);
        ++ptr;
      }
      if (!a[i][j] && d[i][j] + i >= i + L - 1)
        ans += (get(min(d[i][j] + i, n)) - get(min(n, i + L - 2)));
    }
  }

  cout << ans << endl;
}

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

const int N = 4005;

int n, m, P, L;
bool a[N][N];
short l[N][N], r[N][N], u[N][N], d[N][N];
long long ans;

int T[N];
void upd(int x, int v) {
  for (; x <= n; x += x & -x)
    T[x] += v;
}
int get(int x) {
  int res = 0;
  for (; x > 0; x -= x & -x)
    res += T[x];
  return res;
}

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cin >> n >> m >> L >> P;
  for (int i = 1; i <= P; ++i) {
    int u, v;
    cin >> u >> v;
    a[u][v] = 1;
  }

  for (int i = 1; i <= n; ++i) {
    l[i][0] = 0;
    r[i][m + 1] = m + 1;
    for (int j = 1; j <= m; ++j)
      l[i][j] = (a[i][j] ? j : l[i][j - 1]);
    for (int j = m; j >= 1; --j)
      r[i][j] = (a[i][j] ? j : r[i][j + 1]);
  }
  for (int j = 1; j <= m; ++j) {
    u[0][j] = 0;
    d[n + 1][j] = n + 1;
    for (int i = 1; i <= n; ++i)
      u[i][j] = (a[i][j] ? i : u[i - 1][j]);
    for (int i = n; i >= 1; --i)
      d[i][j] = (a[i][j] ? i : d[i + 1][j]);
  }
  for (int i = 1; i <= n; ++i)
    for (int j = 1; j <= m; ++j) {
      d[i][j] = min(d[i][j] - i, r[i][j] - j) - 1;
      u[i][j] = min(i - u[i][j], j - l[i][j]) - 1;
      // cerr << i << ' ' << j << ' ' << d[i][j] << ' ' << u[i][j] << endl;
    }

  for (int h = 1 - m; h <= n - 1; ++h) {
    // cerr << h << endl;
    vector<int> Z;
    vector<pair<int, int>> v;
    for (int i = n; i >= 1; --i) {
      int j = i - h;
      if (j < 1 || j > m)
        continue;
      v.push_back(make_pair(i - u[i][j], i));
    }
    sort(v.begin(), v.end());
    for (int i = 0; i <= n; ++i)
      T[i] = 0;

    int ptr = 0;
    for (int i = 1; i <= n; ++i) {
      int j = i - h;
      if (j < 1 || j > m)
        continue;
      // cerr << h << " -> " << i << ' ' << j << endl;
      while (ptr < (int)v.size() && v[ptr].first <= i) {
        int k = v[ptr].second; // cerr << k << ' ' << v[ptr].first << endl;
        upd(k, 1);
        ++ptr;
      }
      if (!a[i][j] && d[i][j] + i >= i + L - 1)
        ans += (get(min(d[i][j] + i, n)) - get(min(n, i + L - 2)));
    }
  }

  cout << ans << endl;
}