Problem p02580 (C++) — buggy submission, verdict: Runtime Error

#pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < n; i++)
#define cinf(n, x)                                                             \\
  for (int i = 0; i < (n); i++)                                                \\
    cin >> x[i];
#define ft first
#define sc second
#define pb push_back
#define lb lower_bound
#define ub upper_bound
#define all(v) (v).begin(), (v).end()
#define LB(a, x) lb(all(a), x) - a.begin()
#define UB(a, x) ub(all(a), x) - a.begin()
#define mod 1000000007
// #define mod 998244353
#define FS fixed << setprecision(15)
using namespace std;
typedef long long ll;
const double pi = 3.141592653589793;
template <class T> using V = vector<T>;
using Graph = vector<vector<int>>;
using P = pair<ll, ll>;
typedef unsigned long long ull;
typedef long double ldouble;
template <class T> inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
template <class T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}

const ll INF = 1e18;
const int mx = 200005;

class Segtree {
public:
  ll N = 1;
  V<ll> dat;
  explicit Segtree(ll sz) {
    while (N < sz)
      N *= 2;
    dat.reserve(2 * N);
    rep(i, 2 * N) dat[i] = 0;
  }

  // Range Minimum Query -------------------------

  void min_init() {
    for (int i = 0; i < N; i++)
      min_update(i, INF);
  }

  void min_update(ll k, ll a) {
    k += N - 1;
    dat[k] = a;
    while (k > 0) {
      k = (k - 1) / 2;
      dat[k] = min(dat[2 * k + 1], dat[2 * k + 2]);
    }
  }

  ll min_query(ll a, ll b, ll k, ll l, ll r) {
    if (r <= a || b <= l)
      return INF;
    if (a <= l && r <= b)
      return dat[k];
    ll m = (l + r) / 2;
    ll u = min_query(a, b, 2 * k + 1, l, m);
    ll v = min_query(a, b, 2 * k + 2, m, r);
    return min(u, v);
  }

  // Range Maximum Query ---------------------------

  void max_init() {
    for (int i = 0; i < N; i++)
      max_update(i, -INF);
  }

  void max_update(ll k, ll a) {
    k += N - 1;
    dat[k] = a;
    while (k > 0) {
      k = (k - 1) / 2;
      dat[k] = max(dat[2 * k + 1], dat[2 * k + 2]);
    }
  }

  ll max_query(ll a, ll b, ll k, ll l, ll r) {
    if (r <= a || b <= l)
      return -INF;
    if (a <= l && r <= b)
      return dat[k];
    ll m = (l + r) / 2;
    ll u = max_query(a, b, 2 * k + 1, l, m);
    ll v = max_query(a, b, 2 * k + 2, m, r);
    return max(u, v);
  }

  // Range Sum Query -----------------------------

  void sum_update(ll k, ll a) {
    k += N - 1;
    dat[k] += a;
    while (k > 0) {
      k = (k - 1) / 2;
      dat[k] = (dat[2 * k + 1] + dat[2 * k + 2]);
    }
  }

  ll sum_query(ll a, ll b, ll k, ll l, ll r) {
    if (r <= a || b <= l)
      return 0LL;
    if (a <= l && r <= b)
      return dat[k];
    ll m = (l + r) / 2;
    ll u = sum_query(a, b, 2 * k + 1, l, m);
    ll v = sum_query(a, b, 2 * k + 2, m, r);
    return (u + v);
  }

  // その他----------------------------------------
  /*
  ll unit(){
      return ;//単位元
  }
  ll calc(ll a,ll b){
      return ;//演算
  }
  void update(ll k,ll a){
      k+=N-1;
      dat[k]=a;
      while(k>0){
          k=(k-1)/2;
          dat[k]=calc(dat[2*k+1],dat[2*k+2]);
      }
  }
  ll query(ll a,ll b,ll k,ll l,ll r){
      if(r<=a||b<=l)return unit();
      if(a<=l&&r<=b)return dat[k];
      ll m=(l+r)/2;
      ll u=min_query(a,b,2*k+1,l,m);
      ll v=min_query(a,b,2*k+2,m,r);
      return calc(u,v);
  }
  */
};

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  ll H, W, m;
  cin >> H >> W >> m;
  V<ll> h(m), w(m);
  Segtree st(H + 3);
  V<V<ll>> g(W + 3);
  rep(i, m) {
    cin >> h[i] >> w[i];
    h[i]--;
    w[i]--;
    g[w[i]].push_back(i);
    ll v = st.dat[h[i] + st.N - 1];
    st.max_update(h[i], v + 1);
  }
  ll ans = 0;
  rep(i, W) {
    for (ll id : g[i]) {
      ll v = h[id];
      ll u = st.dat[v + st.N - 1];
      st.max_update(v, u - 1);
    }
    chmax(ans, (ll)g[i].size() + st.max_query(0, H, 0, 0, st.N));
    for (ll id : g[i]) {
      ll v = h[id];
      ll u = st.dat[v + st.N - 1];
      st.max_update(v, u + 1);
    }
  }
  cout << ans << endl;
}
// ペナルティ出しても焦らない　ACできると信じろ！！！
// どうしてもわからないときはサンプルで実験　何か見えてくるかも
// 頭で考えてダメなら紙におこせ！！
/*
V,P(大文字)使用不可
乗算などの際にオーバーフローに注意せよ！
(適切にmodをとれ　にぶたんで途中で切り上げろ)
制約をよく読め！
{
    ・全探索できるなら全探索しろ
    ・異常な制約ならそこに注目
}
stringの計算量(扱い)注意
コーナー注意！(特に数値が小さいものについては要検証)
N行出力のときは'¥n'
グリッド上では行先が範囲内におさまるかif文で確認(RE注意)
if文ではちゃんと比較演算子==を使え('='でもエラー出ない)
配列(vector)の大きさが0か1以上かで場合分けせよ(RE注意)
(vector<int> a(m)でm==0というものはできない)
modはなるべく最後に取れ！
doubleを扱うときには(abs)ではなく'fabs'!!!
*/

Error: -11

Fixed submission:

#pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < n; i++)
#define cinf(n, x)                                                             \\
  for (int i = 0; i < (n); i++)                                                \\
    cin >> x[i];
#define ft first
#define sc second
#define pb push_back
#define lb lower_bound
#define ub upper_bound
#define all(v) (v).begin(), (v).end()
#define LB(a, x) lb(all(a), x) - a.begin()
#define UB(a, x) ub(all(a), x) - a.begin()
#define mod 1000000007
// #define mod 998244353
#define FS fixed << setprecision(15)
using namespace std;
typedef long long ll;
const double pi = 3.141592653589793;
template <class T> using V = vector<T>;
using Graph = vector<vector<int>>;
using P = pair<ll, ll>;
typedef unsigned long long ull;
typedef long double ldouble;
template <class T> inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
template <class T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}

const ll INF = 1e18;
const int mx = 200005;

class Segtree {
public:
  ll N = 1;
  V<ll> dat;
  explicit Segtree(ll sz) {
    while (N < sz)
      N *= 2;
    dat.reserve(2 * N);
    rep(i, 2 * N) dat[i] = 0;
  }

  // Range Minimum Query -------------------------

  void min_init() {
    for (int i = 0; i < N; i++)
      min_update(i, INF);
  }

  void min_update(ll k, ll a) {
    k += N - 1;
    dat[k] = a;
    while (k > 0) {
      k = (k - 1) / 2;
      dat[k] = min(dat[2 * k + 1], dat[2 * k + 2]);
    }
  }

  ll min_query(ll a, ll b, ll k, ll l, ll r) {
    if (r <= a || b <= l)
      return INF;
    if (a <= l && r <= b)
      return dat[k];
    ll m = (l + r) / 2;
    ll u = min_query(a, b, 2 * k + 1, l, m);
    ll v = min_query(a, b, 2 * k + 2, m, r);
    return min(u, v);
  }

  // Range Maximum Query ---------------------------

  void max_init() {
    for (int i = 0; i < N; i++)
      max_update(i, -INF);
  }

  void max_update(ll k, ll a) {
    k += N - 1;
    dat[k] = a;
    while (k > 0) {
      k = (k - 1) / 2;
      dat[k] = max(dat[2 * k + 1], dat[2 * k + 2]);
    }
  }

  ll max_query(ll a, ll b, ll k, ll l, ll r) {
    if (r <= a || b <= l)
      return -INF;
    if (a <= l && r <= b)
      return dat[k];
    ll m = (l + r) / 2;
    ll u = max_query(a, b, 2 * k + 1, l, m);
    ll v = max_query(a, b, 2 * k + 2, m, r);
    return max(u, v);
  }

  // Range Sum Query -----------------------------

  void sum_update(ll k, ll a) {
    k += N - 1;
    dat[k] += a;
    while (k > 0) {
      k = (k - 1) / 2;
      dat[k] = (dat[2 * k + 1] + dat[2 * k + 2]);
    }
  }

  ll sum_query(ll a, ll b, ll k, ll l, ll r) {
    if (r <= a || b <= l)
      return 0LL;
    if (a <= l && r <= b)
      return dat[k];
    ll m = (l + r) / 2;
    ll u = sum_query(a, b, 2 * k + 1, l, m);
    ll v = sum_query(a, b, 2 * k + 2, m, r);
    return (u + v);
  }

  // その他----------------------------------------
  /*
  ll unit(){
      return ;//単位元
  }
  ll calc(ll a,ll b){
      return ;//演算
  }
  void update(ll k,ll a){
      k+=N-1;
      dat[k]=a;
      while(k>0){
          k=(k-1)/2;
          dat[k]=calc(dat[2*k+1],dat[2*k+2]);
      }
  }
  ll query(ll a,ll b,ll k,ll l,ll r){
      if(r<=a||b<=l)return unit();
      if(a<=l&&r<=b)return dat[k];
      ll m=(l+r)/2;
      ll u=min_query(a,b,2*k+1,l,m);
      ll v=min_query(a,b,2*k+2,m,r);
      return calc(u,v);
  }
  */
};

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  ll H, W, m;
  cin >> H >> W >> m;
  V<ll> h(m), w(m);
  Segtree st(H);
  V<V<ll>> g(W);
  rep(i, m) {
    cin >> h[i] >> w[i];
    h[i]--;
    w[i]--;
    g[w[i]].push_back(i);
    ll v = st.dat[h[i] + st.N - 1];
    st.max_update(h[i], v + 1);
  }
  ll ans = 0;
  rep(i, W) {
    for (ll id : g[i]) {
      ll v = h[id];
      ll u = st.dat[u + st.N - 1];
      st.max_update(v, u - 1);
    }
    chmax(ans, (ll)g[i].size() + st.max_query(0, H, 0, 0, st.N));
    for (ll id : g[i]) {
      ll v = h[id];
      ll u = st.dat[u + st.N - 1];
      st.max_update(v, u + 1);
    }
  }
  cout << ans << endl;
}
// ペナルティ出しても焦らない　ACできると信じろ！！！
// どうしてもわからないときはサンプルで実験　何か見えてくるかも
// 頭で考えてダメなら紙におこせ！！
/*
V,P(大文字)使用不可
乗算などの際にオーバーフローに注意せよ！
(適切にmodをとれ　にぶたんで途中で切り上げろ)
制約をよく読め！
{
    ・全探索できるなら全探索しろ
    ・異常な制約ならそこに注目
}
stringの計算量(扱い)注意
コーナー注意！(特に数値が小さいものについては要検証)
N行出力のときは'¥n'
グリッド上では行先が範囲内におさまるかif文で確認(RE注意)
if文ではちゃんと比較演算子==を使え('='でもエラー出ない)
配列(vector)の大きさが0か1以上かで場合分けせよ(RE注意)
(vector<int> a(m)でm==0というものはできない)
modはなるべく最後に取れ！
doubleを扱うときには(abs)ではなく'fabs'!!!
*/