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

#include <bits/stdc++.h>
#define ll long long
using namespace std;

typedef pair<int, int> P;

int bit[4010];

void add(int i, int x) {
  while (i < 4010) {
    bit[i] += x;
    i += i & -i;
  }
}

ll get(int i) {
  ll s = 0;
  while (i) {
    s += bit[i];
    i -= i & -i;
  }
  return s;
}

int h, w, l, p, lu[4000][4000], rd[4000][4000];
ll ans = 0;
bool field[4000][4000] = {};

signed main() {
  cin >> h >> w >> l >> p;
  for (int i = 0; i < p; i++) {
    int a, b;
    cin >> a >> b;
    a--;
    b--;
    field[a][b] = true;
  }
  for (int i = 0; i < h; i++) {
    int cnt = 0;
    for (int j = 0; j < w; j++) {
      if (field[i][j])
        cnt = 0;
      else
        cnt++;
      lu[i][j] = cnt;
    }
    cnt = 0;
    for (int j = w - 1; j >= 0; j--) {
      if (field[i][j])
        cnt = 0;
      else
        cnt++;
      rd[i][j] = cnt;
    }
  }
  for (int i = 0; i < w; i++) {
    int cnt = 0;
    for (int j = 0; j < h; j++) {
      if (field[j][i])
        cnt = 0;
      else
        cnt++;
      lu[j][i] = min(cnt, lu[j][i]);
    }
    cnt = 0;
    for (int j = h - 1; j >= 0; j--) {
      if (field[j][i])
        cnt = 0;
      else
        cnt++;
      rd[j][i] = min(cnt, rd[j][i]);
    }
  }
  for (int i = -h + 1; i <= w - 1; i++) {
    for (int j = 0; j < h; j++)
      bit[j + 1] = 0;
    vector<int> vec[4010];
    for (int j = 0; j < h; j++) {
      if (i + j >= 0 && i + j < w && lu[j][i + j])
        vec[j - lu[j][i + j] + 1].push_back(j);
    }
    for (int j = 0; j < h; j++) {
      for (int v : vec[j])
        add(v + 1, 1);
      if (i + j >= 0 && i + j < w && rd[j][i + j] &&
          j + rd[j][i + j] > j + l - 1)
        ans += get(j + rd[j][i + j]) - get(j + l - 1);
    }
  }
  cout << ans << endl;
  return 0;
}


Error: MLE

Fixed submission:

#include <bits/stdc++.h>
#define int long long
using namespace std;

typedef pair<int, int> P;

int bit[4010];

void add(int i, int x) {
  while (i < 4010) {
    bit[i] += x;
    i += i & -i;
  }
}

int get(int i) {
  int s = 0;
  while (i) {
    s += bit[i];
    i -= i & -i;
  }
  return s;
}

int h, w, l, p, lu[4000][4000], rd[4000][4000], ans = 0;
bool field[4000][4000] = {};

signed main() {
  cin >> h >> w >> l >> p;
  for (int i = 0; i < p; i++) {
    int a, b;
    cin >> a >> b;
    a--;
    b--;
    field[a][b] = true;
  }
  for (int i = 0; i < h; i++) {
    int cnt = 0;
    for (int j = 0; j < w; j++) {
      if (field[i][j])
        cnt = 0;
      else
        cnt++;
      lu[i][j] = cnt;
    }
    cnt = 0;
    for (int j = w - 1; j >= 0; j--) {
      if (field[i][j])
        cnt = 0;
      else
        cnt++;
      rd[i][j] = cnt;
    }
  }
  for (int i = 0; i < w; i++) {
    int cnt = 0;
    for (int j = 0; j < h; j++) {
      if (field[j][i])
        cnt = 0;
      else
        cnt++;
      lu[j][i] = min(cnt, lu[j][i]);
    }
    cnt = 0;
    for (int j = h - 1; j >= 0; j--) {
      if (field[j][i])
        cnt = 0;
      else
        cnt++;
      rd[j][i] = min(cnt, rd[j][i]);
    }
  }
  for (int i = -h + 1; i <= w - 1; i++) {
    for (int j = 0; j < h; j++)
      bit[j + 1] = 0;
    vector<int> vec[4010];
    for (int j = 0; j < h; j++) {
      if (i + j >= 0 && i + j < w && lu[j][i + j])
        vec[j - lu[j][i + j] + 1].push_back(j);
    }
    for (int j = 0; j < h; j++) {
      for (int v : vec[j])
        add(v + 1, 1);
      if (i + j >= 0 && i + j < w && rd[j][i + j] &&
          j + rd[j][i + j] > j + l - 1)
        ans += get(j + rd[j][i + j]) - get(j + l - 1);
    }
  }
  cout << ans << endl;
  return 0;
}