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

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <vector>
using namespace std;
typedef long long ll;
typedef pair<ll, ll> P;
typedef double db;

#define fr first
#define sc second
#define pb push_back
#define rep(i, x) for (ll i = 0; i < x; i++)
#define rep1(i, x) for (ll i = 1; i <= x; i++)
#define rrep(i, x) for (ll i = x - 1; i >= 0; i--)
#define rrep1(i, x) for (ll i = x; i > 0; i--)

ll H, W, L, p;
P dots[100000];
bool grid[4000][4000];
int u[4000][4000], b[4000][4000];
int t[4000][4000];
ll ans = 0;
ll U[4000], B[4000];
ll bit[4001];

ll sum(ll i) {
  i++;
  ll res = 0;
  while (i > 0) {
    res += bit[i];
    i -= (i & -i);
  }
  return res;
}

void add(ll i, ll x) {
  i++;
  while (i <= 4000) {
    bit[i] += x;
    i += (i & -i);
  }
  return;
}
// U  B
priority_queue<P, vector<P>, greater<P>>
    q; //(????????§??¨????????????????????????id???)
void calc(ll n) {
  memset(bit, 0, sizeof(bit));
  // rep(i,n) cout<<U[i]<<" ";
  // cout<<endl;
  // rep(i,n) cout<<B[i]<<" ";
  // cout<<endl;
  while (!q.empty())
    q.pop();
  rep(i, n) {
    if (i >= L - 1) {
      if (U[i - L + 1] == -1 || U[i - L + 1] < L - 1)
        goto nex;
      add(0, 1);
      add(i - L + 1 + 1, -1);
      q.push(P(i - L + 1 + U[i - L + 1], i - L + 1));
    }
  nex:;
    if (B[i] >= L - 1) {
      ans += sum(i - B[i]);
    }
    while (q.size() && q.top().fr == i) {
      P x = q.top();
      q.pop();
      add(0, -1);
      add(x.sc + 1, 1);
    }
  }
  return;
}

int main() {
  cin >> H >> W >> L >> p;
  rep(i, p) {
    cin >> dots[i].fr >> dots[i].sc;
    dots[i].fr--;
    dots[i].sc--;
    grid[dots[i].fr][dots[i].sc] = 1;
  }
  rep(i, H) rrep(j, W) {
    if (grid[i][j])
      u[i][j] = -1;
    else if (j == W - 1)
      u[i][j] = 0;
    else
      u[i][j] = u[i][j + 1] + 1;
  }
  rep(j, W) rrep(i, H) {
    if (grid[i][j])
      t[i][j] = -1;
    else if (i == H - 1)
      t[i][j] = 0;
    else
      t[i][j] = t[i + 1][j] + 1;
  }
  rep(i, H) rep(j, W) { u[i][j] = min(t[i][j], u[i][j]); }

  rep(i, H) rep(j, W) {
    if (grid[i][j])
      b[i][j] = -1;
    else if (j == 0)
      b[i][j] = 0;
    else
      b[i][j] = b[i][j - 1] + 1;
  }
  rep(j, W) rep(i, H) {
    if (grid[i][j])
      t[i][j] = -1;
    else if (i == 0)
      t[i][j] = 0;
    else
      t[i][j] = t[i - 1][j] + 1;
  }
  rep(i, H) rep(j, W) { b[i][j] = min(t[i][j], b[i][j]); }
  /*cout<<endl;
  rep(i,H){
          rep(j,W){
                  cout<<grid[i][j]<<" ";
          }
          cout<<endl;
  }
  cout<<endl;

  rep(i,H){
          rep(j,W){
                  cout<<u[i][j]<<" ";
          }
          cout<<endl;
  }
  cout<<endl;

  rep(i,H){
          rep(j,W){
                  cout<<b[i][j]<<" ";
          }
          cout<<endl;
  }
  */
  rep(j, W) {
    for (ll k = 0; k < min(H, W - j); k++) {
      U[k] = u[k][j + k];
      B[k] = b[k][j + k];
    }
    calc(min(H, W - j));
  }
  rep1(i, H - 1) {
    for (ll k = 0; k < min(W, H - i); k++) {
      U[k] = u[i + k][k];
      B[k] = b[i + k][k];
    }
    calc(min(W, H - i));
  }
  cout << ans << endl;
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <vector>
using namespace std;
typedef long long ll;
typedef pair<ll, ll> P;
typedef double db;

#define fr first
#define sc second
#define pb push_back
#define rep(i, x) for (ll i = 0; i < x; i++)
#define rep1(i, x) for (ll i = 1; i <= x; i++)
#define rrep(i, x) for (ll i = x - 1; i >= 0; i--)
#define rrep1(i, x) for (ll i = x; i > 0; i--)

ll H, W, L, p;
P dots[100000];
bool grid[4000][4000];
ll u[4000][4000], b[4000][4000];
ll t[4000][4000], y[4000][4000];
ll ans = 0;
ll U[4000], B[4000];
ll bit[4001];

ll sum(ll i) {
  i++;
  ll res = 0;
  while (i > 0) {
    res += bit[i];
    i -= (i & -i);
  }
  return res;
}

void add(ll i, ll x) {
  i++;
  while (i <= 4000) {
    bit[i] += x;
    i += (i & -i);
  }
  return;
}
// U  B
priority_queue<P> q; //(????????§??¨????????????????????????id???)
void calc(ll n) {
  memset(bit, 0, sizeof(bit));
  // rep(i,n) cout<<U[i]<<" ";
  // cout<<endl;
  // rep(i,n) cout<<B[i]<<" ";
  // cout<<endl;
  while (!q.empty())
    q.pop();
  rep(i, n) {
    if (i >= L - 1) {
      if (U[i - L + 1] == -1 || U[i - L + 1] < L - 1)
        goto nex;
      add(0, 1);
      add(i - L + 1 + 1, -1);
      q.push(P(i - L + 1 + U[i - L + 1], i - L + 1));
    }
  nex:;
    if (B[i] >= L - 1) {
      ans += sum(i - B[i]);
    }
    while (q.size() && q.top().fr == i) {
      P x = q.top();
      q.pop();
      add(0, -1);
      add(x.sc + 1, 1);
    }
  }
  return;
}

int main() {
  cin >> H >> W >> L >> p;
  rep(i, p) {
    cin >> dots[i].fr >> dots[i].sc;
    dots[i].fr--;
    dots[i].sc--;
    grid[dots[i].fr][dots[i].sc] = 1;
  }
  rep(i, H) rrep(j, W) {

    if (grid[i][j])
      y[i][j] = -1;
    else if (j == W - 1)
      y[i][j] = 0;
    else
      y[i][j] = y[i][j + 1] + 1;
  }
  rep(j, W) rrep(i, H) {
    if (grid[i][j])
      t[i][j] = -1;
    else if (i == H - 1)
      t[i][j] = 0;
    else
      t[i][j] = t[i + 1][j] + 1;
  }
  rep(i, H) rep(j, W) { u[i][j] = min(t[i][j], y[i][j]); }

  rep(i, H) rep(j, W) {
    if (grid[i][j])
      y[i][j] = -1;
    else if (j == 0)
      y[i][j] = 0;
    else
      y[i][j] = y[i][j - 1] + 1;
  }
  rep(j, W) rep(i, H) {
    if (grid[i][j])
      t[i][j] = -1;
    else if (i == 0)
      t[i][j] = 0;
    else
      t[i][j] = t[i - 1][j] + 1;
  }
  rep(i, H) rep(j, W) { b[i][j] = min(t[i][j], y[i][j]); }
  /*cout<<endl;
  rep(i,H){
          rep(j,W){
                  cout<<grid[i][j]<<" ";
          }
          cout<<endl;
  }
  cout<<endl;

  rep(i,H){
          rep(j,W){
                  cout<<u[i][j]<<" ";
          }
          cout<<endl;
  }
  cout<<endl;

  rep(i,H){
          rep(j,W){
                  cout<<b[i][j]<<" ";
          }
          cout<<endl;
  }
  */
  rep(j, W) {
    for (ll k = 0; k < min(H, W - j); k++) {
      U[k] = u[k][j + k];
      B[k] = b[k][j + k];
    }
    calc(min(H, W - j));
  }
  rep1(i, H - 1) {
    for (ll k = 0; k < min(W, H - i); k++) {
      U[k] = u[i + k][k];
      B[k] = b[i + k][k];
    }
    calc(min(W, H - i));
  }
  cout << ans << endl;
}