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

#include <algorithm>
#include <bitset>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <vector>
using namespace std;

typedef pair<int, int> P;
#define rep(i, n) for (int i = 0; i < (n); i++)
#define all(c) (c).begin(), (c).end()
#define uniq(c) c.erase(unique(all(c)), (c).end())
#define index(xs, x) (int)(lower_bound(all(xs), x) - xs.begin())
#define _1 first
#define _2 second
#define pb push_back
#define INF 1145141919
#define MOD 1000000007
bool S[4000];
int B[4001];
void BIT_add(int i) {
  for (int x = i + 1; x <= 4000; x += x & -x)
    B[x]++;
}
int BIT_sum(int i) {
  int s = 0;
  for (int x = i + 1; x > 0; x -= x & -x)
    s += B[x];
  return s;
}

int H, W, L, N;
vector<int> GX[4000], GY[4000];
int GXh[4000], GYh[4000];

signed main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cin >> H >> W >> L >> N;
  rep(i, N) {
    int x, y;
    cin >> y >> x;
    x--, y--;
    GX[y].pb(x);
    GY[x].pb(y);
  }
  rep(y, H) sort(all(GX[y]));
  rep(x, W) sort(all(GY[x]));

  long long ctr = 0;
  for (int d = 1 - H; d < W; d++) {
    int bx = 0, by = 0;
    if (d < 0)
      by = -d;
    else
      bx = d;
    int len = min(H - by, W - bx);
    rep(x, W) GYh[x] = (int)GY[x].size() - 1;
    rep(y, H) GXh[y] = (int)GX[y].size() - 1;
    rep(i, 4000) S[i] = 0;
    rep(i, 4001) B[i] = 0;
    auto add = [&](int x, int y) {
      int s = max(x - bx, y - by);
      if (S[s])
        return;
      S[s] = 1;
      BIT_add(s);
    };

    for (int s = len - 1; s >= 0; s--) {
      int x = bx + s, y = by + s;
      int mx = W, my = H;
      while (GXh[y] >= 0 && GX[y][GXh[y]] >= x)
        add(mx = GX[y][GXh[y]--], y);
      while (GYh[x] >= 0 && GY[x][GYh[x]] >= y)
        add(x, my = GY[x][GYh[x]--]);
      int X = min(mx - bx, my - by);
      // count [s+L-1, X)
      if (s + L - 1 >= X)
        continue;
      // cout<< "("<<x<<","<<y<<"): ["<<s+L-1<<","<<X<<") | "; rep(i, W)
      // cout<<S[i]<<",";cout<<"\\n"; for (int p=s+L-1; p<X; p++) ctr += 1-S[p];
      ctr += (X - (s + L - 1)) - (BIT_sum(X - 1) - BIT_sum(s + L - 2));
    }
  }
  cout << ctr << "\\n";
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <bitset>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <vector>
using namespace std;

typedef pair<int, int> P;
#define rep(i, n) for (int i = 0; i < (n); i++)
#define all(c) (c).begin(), (c).end()
#define uniq(c) c.erase(unique(all(c)), (c).end())
#define index(xs, x) (int)(lower_bound(all(xs), x) - xs.begin())
#define _1 first
#define _2 second
#define pb push_back
#define INF 1145141919
#define MOD 1000000007

int H, W, L, N;
vector<int> GX[4000], GY[4000];
int GXh[4000], GYh[4000];
bool S[4000];

signed main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cin >> H >> W >> L >> N;
  rep(i, N) {
    int x, y;
    cin >> y >> x;
    x--, y--;
    GX[y].pb(x);
    GY[x].pb(y);
  }
  rep(y, H) sort(all(GX[y]));
  rep(x, W) sort(all(GY[x]));

  long long ctr = 0;
  for (int d = 1 - H; d < W; d++) {
    int bx = 0, by = 0;
    if (d < 0)
      by = -d;
    else
      bx = d;
    int len = min(H - by, W - bx);
    rep(x, W) GYh[x] = (int)GY[x].size() - 1;
    rep(y, H) GXh[y] = (int)GX[y].size() - 1;
    rep(i, 4000) S[i] = false;
    set<int> vs;
    auto add = [&](int x, int y) {
      int s = max(x - bx, y - by);
      if (S[s])
        return;
      S[s] = true;
      vs.insert(s);
    };

    for (int s = len - 1; s >= 0; s--) {
      int x = bx + s, y = by + s;
      int mx = W, my = H;
      while (GXh[y] >= 0 && GX[y][GXh[y]] >= x)
        add(mx = GX[y][GXh[y]--], y);
      while (GYh[x] >= 0 && GY[x][GYh[x]] >= y)
        add(x, my = GY[x][GYh[x]--]);
      int X = min(mx - bx, my - by);
      // count [s+L-1, X)
      if (s + L - 1 >= X)
        continue;
      // for (int x: vs)cout<<x<<",";cout<<"\\n";
      // ctr += vs.upper_bound(s+L-1) - vs.lower_bound(s+L-1);
      // cout<< "("<<x<<","<<y<<"): ["<<s+L-1<<","<<X<<") | "; rep(i, W)
      // cout<<S[i]<<",";cout<<"\\n";
      for (int p = s + L - 1; p < X; p++)
        ctr += 1 - S[p];
    }
  }
  cout << ctr << "\\n";
  return 0;
}