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

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

struct BIT {
  int t[5000];
  void init() {
    for (int i = 0; i < 5000; i++) {
      t[i] = 0;
    }
  }
  void add(int i, int x) {
    i += 10;

    while (i < 5000) {
      t[i] += x;
      i += (i & -i);
    }
  }
  int sum(int i) {
    i += 10;

    int res = 0;
    while (i > 0) {
      res += t[i];
      i -= (i & -i);
    }
    return res;
  }
};

BIT T;
int H, W, L, P;
short t[4000][4000];

short A[4000][4000];
short B[4000][4000];
short C[4000][4000];
short D[4000][4000];

vector<short> G[5000];

ll solve(int y, int x) {
  for (int i = 0; i < 5000; i++)
    G[i].clear();
  T.init();

  ll res = 0;

  for (int i = 0; i < 5000; i++) {
    int py = y + i;
    int px = x + i;
    if (py >= H || px >= W)
      break;
    if (i - L + 1 >= 0) {
      int ay = py - L + 1;
      int ax = px - L + 1;

      int len = min(C[ay][ax], D[ay][ax]) - 1;

      if (i - L + 1 + len >= i) {
        T.add(i - L + 1, 1);
        G[i - L + 1 + len].push_back(i - L + 1);
      }
    }

    int fr = min(A[py][px], B[py][px]);

    if (fr >= 3) {
      ll v = T.sum(4500) - T.sum(i - fr);
      res += v;
    }

    for (int j = 0; j < (int)G[i].size(); j++) {
      T.add(G[i][j], -1);
    }
  }

  return res;
}

int main() {

  scanf("%d %d %d %d", &H, &W, &L, &P);
  for (int i = 0; i < P; i++) {
    int y, x;
    scanf("%d %d", &y, &x);
    y--, x--;

    t[y][x] = 1;
  }

  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      if (t[i][j] == 1) {
        A[i][j] = 0;
        continue;
      }
      A[i][j] = 1;
      if (j > 0) {
        A[i][j] += A[i][j - 1];
      }
    }
  }

  for (int j = 0; j < W; j++) {
    for (int i = 0; i < H; i++) {
      if (t[i][j] == 1) {
        B[i][j] = 0;
        continue;
      }
      B[i][j] = 1;
      if (i > 0) {
        B[i][j] += B[i - 1][j];
      }
    }
  }

  for (int i = 0; i < H; i++) {
    for (int j = W - 1; j >= 0; j--) {
      if (t[i][j] == 1) {
        C[i][j] = 0;
        continue;
      }
      C[i][j] = 1;
      if (j + 1 < W) {
        C[i][j] += C[i][j + 1];
      }
    }
  }

  for (int j = 0; j < W; j++) {
    for (int i = H - 1; i >= 0; i--) {
      if (t[i][j] == 1) {
        D[i][j] = 0;
        continue;
      }
      D[i][j] = 1;
      if (i + 1 < H) {
        D[i][j] += D[i + 1][j];
      }
    }
  }

  ll ans = 0;
  for (int i = 0; i < H; i++) {
    ans += solve(i, 0);
  }
  for (int i = 1; i < W; i++) {
    ans += solve(0, i);
  }

  printf("%lld\\n", ans);
  return 0;
}


Error: MLE

Fixed submission:

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

struct BIT {
  int t[5000];
  void init() {
    for (int i = 0; i < 5000; i++) {
      t[i] = 0;
    }
  }
  void add(int i, int x) {
    i += 10;

    while (i < 5000) {
      t[i] += x;
      i += (i & -i);
    }
  }
  int sum(int i) {
    i += 10;

    int res = 0;
    while (i > 0) {
      res += t[i];
      i -= (i & -i);
    }
    return res;
  }
};

BIT T;
int H, W, L, P;
int t[4000][4000];

int A[4000][4000];
int B[4000][4000];
int C[4000][4000];
int D[4000][4000];

vector<int> G[5000];

ll solve(int y, int x) {
  for (int i = 0; i < 5000; i++)
    G[i].clear();
  T.init();

  ll res = 0;

  for (int i = 0; i < 5000; i++) {
    int py = y + i;
    int px = x + i;
    if (py >= H || px >= W)
      break;
    if (i - L + 1 >= 0) {
      int ay = py - L + 1;
      int ax = px - L + 1;

      int len = min(C[ay][ax], D[ay][ax]) - 1;

      if (i - L + 1 + len >= i) {
        T.add(i - L + 1, 1);
        G[i - L + 1 + len].push_back(i - L + 1);
      }
    }

    int fr = min(A[py][px], B[py][px]);

    if (fr >= 3) {
      ll v = T.sum(4500) - T.sum(i - fr);
      res += v;
    }

    for (int j = 0; j < (int)G[i].size(); j++) {
      T.add(G[i][j], -1);
    }
  }

  return res;
}

int main() {

  scanf("%d %d %d %d", &H, &W, &L, &P);
  for (int i = 0; i < P; i++) {
    int y, x;
    scanf("%d %d", &y, &x);
    y--, x--;

    t[y][x] = 1;
  }

  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      if (t[i][j] == 1) {
        A[i][j] = 0;
        continue;
      }
      A[i][j] = 1;
      if (j > 0) {
        A[i][j] += A[i][j - 1];
      }
    }
  }

  for (int j = 0; j < W; j++) {
    for (int i = 0; i < H; i++) {
      if (t[i][j] == 1) {
        B[i][j] = 0;
        continue;
      }
      B[i][j] = 1;
      if (i > 0) {
        B[i][j] += B[i - 1][j];
      }
    }
  }

  for (int i = 0; i < H; i++) {
    for (int j = W - 1; j >= 0; j--) {
      if (t[i][j] == 1) {
        C[i][j] = 0;
        continue;
      }
      C[i][j] = 1;
      if (j + 1 < W) {
        C[i][j] += C[i][j + 1];
      }
    }
  }

  for (int j = 0; j < W; j++) {
    for (int i = H - 1; i >= 0; i--) {
      if (t[i][j] == 1) {
        D[i][j] = 0;
        continue;
      }
      D[i][j] = 1;
      if (i + 1 < H) {
        D[i][j] += D[i + 1][j];
      }
    }
  }

  ll ans = 0;
  for (int i = 0; i < H; i++) {
    ans += solve(i, 0);
  }
  for (int i = 1; i < W; i++) {
    ans += solve(0, i);
  }

  printf("%lld\\n", ans);
  return 0;
}