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

#include <bits/stdc++.h>

using namespace std;
#define int long long
#define rep(i, n) for (int i = 0; i < (int)n; i++)

int tr_2d[5002][5002];

map<int, int> zip_x, zip_y;
int unzip_x[5000], unzip_y[5000];

pair<int, int> compress(vector<int> &x, vector<int> &y) {
  // zipで座標->index
  // unzipでindex->座標
  // x,yは書き換えられるので注意
  sort(x.begin(), x.end());
  sort(y.begin(), y.end());
  x.erase(unique(x.begin(), x.end()), x.end());
  y.erase(unique(y.begin(), y.end()), y.end());
  rep(i, x.size()) {
    zip_x[x[i]] = i;
    unzip_x[i] = x[i];
  }
  rep(i, y.size()) {
    zip_y[y[i]] = i;
    unzip_y[i] = y[i];
  }
  return make_pair(x.size(), y.size());
}

void Imos2D(int n) {
  rep(i, n + 1) rep(j, n) tr_2d[i][j + 1] += tr_2d[i][j];
  rep(i, n) rep(j, n + 1) tr_2d[i + 1][j] += tr_2d[i][j];
}

int sum(int xl, int xr, int yd, int yu) {
  return tr_2d[xr][yu] - tr_2d[xl][yu] + tr_2d[xl][yd] - tr_2d[xr][yd];
}

signed main() {

  int n, m;
  cin >> n >> m;
  vector<int> tr_x(n), tr_x2(n), tr_y(n), tr_y2(n);
  rep(i, n + 2) {
    rep(j, n + 2) { tr_2d[i][j] = 0; }
  }

  rep(i, n) {
    int x, y;
    cin >> x >> y;
    tr_x[i] = x;
    tr_x2[i] = x;
    tr_y[i] = y;
    tr_y2[i] = y;
  }
  // 座圧
  pair<int, int> size = compress(tr_x2, tr_y2);
  // cout<<size.first<<size.second<<endl;
  rep(i, n) {
    int id_x = zip_x[tr_x[i]];
    int id_y = zip_y[tr_y[i]];
    tr_2d[id_x + 1][id_y + 1]++;
  }
  // rep(i,n){
  //   rep(j,n-1){
  //     cout<<tr_2d[i][j]<<" ";
  //   }
  //   cout<<tr_2d[i][n-1]<<endl;
  // }

  // 2次元累積和
  Imos2D(n);
  // rep(i,n+1){
  //   rep(j,n){
  //     cout<<s[i][j]<<" ";
  //   }
  //   cout<<s[i][n]<<endl;
  // }

  rep(i, m) {
    int xl, xr, yd, yu;
    cin >> xl >> yd >> xr >> yu;
    auto ixl = lower_bound(unzip_x, unzip_x + size.first, xl) - unzip_x;
    auto ixr = upper_bound(unzip_x, unzip_x + size.first, xr) - unzip_x - 1;
    auto iyd = lower_bound(unzip_y, unzip_y + size.second, yd) - unzip_y;
    auto iyu = upper_bound(unzip_y, unzip_y + size.second, yu) - unzip_y - 1;
    // cout << xl<<" "<<xr<<" : "<<ixl<< " " <<ixr<<endl;
    // cout << yd<<" "<<yu<<" : "<<iyd<< " " <<iyu<<endl;
    cout << sum(ixl, ixr + 1, iyd, iyu + 1) << endl;
  }

  return 0;
}


Error: MLE

Fixed submission:

#include <bits/stdc++.h>

using namespace std;
#define int long long
#define rep(i, n) for (int i = 0; i < (int)n; i++)

int tr_2d[5001][5001];
int s[5002][5002];

map<int, int> zip_x, zip_y;
int unzip_x[5000], unzip_y[5000];

pair<int, int> compress(vector<int> &x, vector<int> &y) {
  // zipで座標->index
  // unzipでindex->座標
  // x,yは書き換えられるので注意
  sort(x.begin(), x.end());
  sort(y.begin(), y.end());
  x.erase(unique(x.begin(), x.end()), x.end());
  y.erase(unique(y.begin(), y.end()), y.end());
  rep(i, x.size()) {
    zip_x[x[i]] = i;
    unzip_x[i] = x[i];
  }
  rep(i, y.size()) {
    zip_y[y[i]] = i;
    unzip_y[i] = y[i];
  }
  return make_pair(x.size(), y.size());
}

void Imos2D(int n) {
  rep(i, n + 1) rep(j, n + 1) s[i + 1][j + 1] = tr_2d[i][j];
  rep(i, n + 1) rep(j, n) s[i][j + 1] += s[i][j];
  rep(i, n) rep(j, n + 1) s[i + 1][j] += s[i][j];
}

int sum(int xl, int xr, int yd, int yu) {
  return s[xr][yu] - s[xl][yu] + s[xl][yd] - s[xr][yd];
}

signed main() {

  int n, m;
  cin >> n >> m;
  vector<int> tr_x(n), tr_x2(n), tr_y(n), tr_y2(n);
  rep(i, n + 1) {
    rep(j, n + 1) { tr_2d[i][j] = 0; }
  }

  rep(i, n) {
    int x, y;
    cin >> x >> y;
    tr_x[i] = x;
    tr_x2[i] = x;
    tr_y[i] = y;
    tr_y2[i] = y;
  }
  // 座圧
  pair<int, int> size = compress(tr_x2, tr_y2);
  // cout<<size.first<<size.second<<endl;
  rep(i, n) {
    int id_x = zip_x[tr_x[i]];
    int id_y = zip_y[tr_y[i]];
    tr_2d[id_x][id_y]++;
  }
  // rep(i,n){
  //   rep(j,n-1){
  //     cout<<tr_2d[i][j]<<" ";
  //   }
  //   cout<<tr_2d[i][n-1]<<endl;
  // }

  // 2次元累積和
  rep(i, n + 2) rep(j, n + 2) s[i][j] = 0;
  Imos2D(n);
  // rep(i,n+1){
  //   rep(j,n){
  //     cout<<s[i][j]<<" ";
  //   }
  //   cout<<s[i][n]<<endl;
  // }

  rep(i, m) {
    int xl, xr, yd, yu;
    cin >> xl >> yd >> xr >> yu;
    auto ixl = lower_bound(unzip_x, unzip_x + size.first, xl) - unzip_x;
    auto ixr = upper_bound(unzip_x, unzip_x + size.first, xr) - unzip_x - 1;
    auto iyd = lower_bound(unzip_y, unzip_y + size.second, yd) - unzip_y;
    auto iyu = upper_bound(unzip_y, unzip_y + size.second, yu) - unzip_y - 1;
    // cout << xl<<" "<<xr<<" : "<<ixl<< " " <<ixr<<endl;
    // cout << yd<<" "<<yu<<" : "<<iyd<< " " <<iyu<<endl;
    cout << sum(ixl, ixr + 1, iyd, iyu + 1) << endl;
  }

  return 0;
}