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

#include "bits/stdc++.h"
#include <random>
using namespace std;
typedef unsigned long long _ulong;
typedef long long int lint;
typedef pair<lint, lint> plint;
typedef pair<double long, double long> pld;
#define ALL(x) (x).begin(), (x).end()
#define SZ(x) ((lint)(x).size())
#define FOR(i, begin, end)                                                     \\
  for (lint i = (begin), i##_end_ = (end); i < i##_end_; i++)
#define IFOR(i, begin, end)                                                    \\
  for (lint i = (end)-1, i##_begin_ = (begin); i >= i##_begin_; i--)
#define REP(i, n) FOR(i, 0, n)
#define IREP(i, n) IFOR(i, 0, n)
#define endk '\\n'
template <class T> bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> bool chmin(T &a, const T &b) {
  if (b < a) {
    a = b;
    return 1;
  }
  return 0;
}
const lint MOD = 1e9 + 7, INF = 1e18;
lint dx[8] = {0, -1, 1, 0, 1, -1, 1, -1}, dy[8] = {1, 0, 0, -1, -1, -1, 1, 1};

lint H, W, M, h, w;
lint cnt_H[300000], cnt_W[300000];
plint _cnt_H[300000], _cnt_W[300000];
set<plint> pos;

int main() {
  cin >> H >> W >> M;
  REP(i, M) {
    cin >> h >> w;
    h--;
    w--;
    cnt_H[h]++;
    cnt_W[w]++;
    pos.insert({h, w});
  }
  lint maxv_H = 0, maxv_W = 0;
  REP(i, H) {
    _cnt_H[i] = {-cnt_H[i], i};
    chmax(maxv_H, cnt_H[i]);
  }
  REP(i, W) {
    _cnt_W[i] = {-cnt_W[i], i};
    chmax(maxv_W, cnt_W[i]);
  }
  sort(_cnt_H, _cnt_H + H);
  sort(_cnt_W, _cnt_W + W);
  lint idx_H = 0, idx_W = 0;
  lint maxv = 0;
  while (idx_H < H && -_cnt_H[idx_H].first == maxv_H)
    idx_H++;
  while (idx_W < W && -_cnt_W[idx_W].first == maxv_W)
    idx_W++;
  if (idx_H * idx_W > M) {
    cout << maxv_H + maxv_W << endk;
    return 0;
  }
  idx_H = 0, idx_W = 0;
  while (idx_H < H && -_cnt_H[idx_H].first >= maxv_H) {
    idx_W = 0;
    while (idx_W < W && -_cnt_W[idx_W].first >= maxv_W) {
      lint score = -_cnt_H[idx_H].first - _cnt_W[idx_W].first;
      if (pos.find({_cnt_H[idx_H].second, _cnt_W[idx_W].second}) != pos.end())
        score--;
      chmax(maxv, score);
      idx_W++;
    }
    idx_H++;
  }
  cout << maxv << endk;
}


Error: TLE

Fixed submission:

#include "bits/stdc++.h"
#include <random>
using namespace std;
typedef unsigned long long _ulong;
typedef long long int lint;
typedef pair<lint, lint> plint;
typedef pair<double long, double long> pld;
#define ALL(x) (x).begin(), (x).end()
#define SZ(x) ((lint)(x).size())
#define FOR(i, begin, end)                                                     \\
  for (lint i = (begin), i##_end_ = (end); i < i##_end_; i++)
#define IFOR(i, begin, end)                                                    \\
  for (lint i = (end)-1, i##_begin_ = (begin); i >= i##_begin_; i--)
#define REP(i, n) FOR(i, 0, n)
#define IREP(i, n) IFOR(i, 0, n)
#define endk '\\n'
template <class T> bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> bool chmin(T &a, const T &b) {
  if (b < a) {
    a = b;
    return 1;
  }
  return 0;
}
const lint MOD = 1e9 + 7, INF = 1e18;
lint dx[8] = {0, -1, 1, 0, 1, -1, 1, -1}, dy[8] = {1, 0, 0, -1, -1, -1, 1, 1};

lint H, W, M, h, w;
lint cnt_H[300000], cnt_W[300000];
plint _cnt_H[300000], _cnt_W[300000];
set<plint> pos;

int main() {
  cin >> H >> W >> M;
  REP(i, M) {
    cin >> h >> w;
    h--;
    w--;
    cnt_H[h]++;
    cnt_W[w]++;
    pos.insert({h, w});
  }
  lint maxv_H = 0, maxv_W = 0;
  REP(i, H) {
    _cnt_H[i] = {-cnt_H[i], i};
    chmax(maxv_H, cnt_H[i]);
  }
  REP(i, W) {
    _cnt_W[i] = {-cnt_W[i], i};
    chmax(maxv_W, cnt_W[i]);
  }
  sort(_cnt_H, _cnt_H + H);
  sort(_cnt_W, _cnt_W + W);
  lint idx_H = 0, idx_W = 0;
  lint maxv = 0;
  lint len_H = 0, len_W = 0;
  while (idx_H < H && -_cnt_H[idx_H].first == maxv_H)
    len_H++;
  while (idx_W < W && -_cnt_W[idx_W].first == maxv_W)
    len_W++;
  if (len_H * len_W > M) {
    cout << maxv_H - maxv_W << endk;
    return 0;
  }
  while (idx_H < H && -_cnt_H[idx_H].first >= maxv_H) {
    idx_W = 0;
    while (idx_W < W && -_cnt_W[idx_W].first >= maxv_W) {
      lint score = -_cnt_H[idx_H].first - _cnt_W[idx_W].first;
      if (pos.find({_cnt_H[idx_H].second, _cnt_W[idx_W].second}) != pos.end())
        score--;
      chmax(maxv, score);
      idx_W++;
    }
    idx_H++;
  }
  cout << maxv << endk;
}