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

#include <bits/stdc++.h>
using namespace std;

using pii = pair<int, int>;
using ll = long long;
#define rep(i, j) for (int i = 0; i < (int)(j); i++)
#define repeat(i, j, k) for (int i = (j); i < (int)(k); i++)
#define all(v) v.begin(), v.end()
#define debug(x) cerr << #x << " : " << x << endl

template <class T> bool set_min(T &a, const T &b) {
  return a > b ? a = b, true : false;
}
template <class T> bool set_max(T &a, const T &b) {
  return a < b ? a = b, true : false;
}
// vector
template <class T> istream &operator>>(istream &is, vector<T> &v) {
  for (T &a : v)
    is >> a;
  return is;
}
template <class T> ostream &operator<<(ostream &os, const vector<T> &v) {
  for (const T &t : v)
    os << "\\t" << t;
  return os << endl;
}
// pair
template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &v) {
  return os << "<" << v.first << ", " << v.second << ">";
}

const int INF = 1 << 30;
const ll INFL = 1LL << 60;

class Solver {
public:
  int P, R, T;
  vector<int> L;
  vector<vector<int>> N;
  vector<pii> PR;

  bool check_terminated(vector<int> &need) {
    bool terminated = true;
    rep(r, R) terminated &= need[r] == 0;
    return terminated;
  }

  bool is_avoidable(int t) {
    vector<vector<int>> need = N;
    vector<int> left = L;

    vector<bool> terminated(P);
    int terminated_num = 0;

    // O(t * R) ?
    rep(i, t) {
      int p = PR[i].first, r = PR[i].second;
      left[r]--;
      need[p][r]--;
      if (left[r] < 0) {
        return false; // lack of resource !
      }
      if (need[p][r] == 0) {
        assert(not terminated[p]);
        if (check_terminated(need[p])) {
          rep(r2, R) left[r2] += N[p][r2] - need[p][r2];
          terminated[p] = true;
          terminated_num++;
        }
      }
    }

    bool flg = true;
    while (terminated_num < P and flg) {
      flg = false;
      rep(p, P) {
        if (terminated[p])
          continue;
        bool terminatable = true;
        rep(r, R) terminatable &= need[p][r] <= left[r];
        if (terminatable) {
          rep(r, R) left[r] += N[p][r] - need[p][r];
          terminated[p] = true;
          terminated_num++;
          flg = true;
        }
      }
    }
    // cerr << "! " << t << " " << terminated_num << endl;
    return terminated_num == P;
  }

  bool solve() {
    cin >> P >> R >> T;
    L.resize(R);
    cin >> L;
    N.resize(P, vector<int>(R));
    cin >> N;
    PR.resize(T);
    rep(i, T) {
      cin >> PR[i].first >> PR[i].second;
      PR[i].first--;
      PR[i].second--;
    }

    int l = -1, r = T + 1;
    while (l + 1 < r) {
      int m = (l + r) / 2;
      // cerr << m << " " << l << " " << r << endl;
      (is_avoidable(m) ? l : r) = m;
    }
    cout << (r > T ? -1 : r) << endl;
    return 0;
  }
};

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  Solver s;
  s.solve();
  return 0;
}

Error: 0
state t = 4
left 	1	2

		2	1
		0	2


! 4 2
state t = 6
left 	1	0

		2	0
		0	1


! 6 0
state t = 5
left 	1	1

		2	0
		0	2


! 5 0


Fixed submission:

#include <bits/stdc++.h>
using namespace std;

using pii = pair<int, int>;
using ll = long long;
#define rep(i, j) for (int i = 0; i < (int)(j); i++)
#define repeat(i, j, k) for (int i = (j); i < (int)(k); i++)
#define all(v) v.begin(), v.end()
#define debug(x) cerr << #x << " : " << x << endl

template <class T> bool set_min(T &a, const T &b) {
  return a > b ? a = b, true : false;
}
template <class T> bool set_max(T &a, const T &b) {
  return a < b ? a = b, true : false;
}
// vector
template <class T> istream &operator>>(istream &is, vector<T> &v) {
  for (T &a : v)
    is >> a;
  return is;
}
template <class T> ostream &operator<<(ostream &os, const vector<T> &v) {
  for (const T &t : v)
    os << "\\t" << t;
  return os << endl;
}
// pair
template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &v) {
  return os << "<" << v.first << ", " << v.second << ">";
}

const int INF = 1 << 30;
const ll INFL = 1LL << 60;

class Solver {
public:
  int P, R, T;
  vector<int> L;
  vector<vector<int>> N;
  vector<pii> PR;

  // O(t)
  tuple<vector<vector<int>>, vector<int>> calc_state(int t) {
    vector<vector<int>> need = N;
    vector<int> left;
    left = L;
    rep(i, t) {
      int p = PR[i].first, r = PR[i].second;
      left[r]--;
      need[p][r]--;
    }
    cerr << "state t = " << t << endl;
    cerr << "left " << left << endl;
    cerr << need << endl;
    return make_tuple(need, left);
  }

  bool is_avoidable(int t) {
    vector<vector<int>> need;
    vector<int> left;
    tie(need, left) = calc_state(t);

    // check lack of resource
    for (int l : left)
      if (l < 0)
        return false;

    vector<bool> terminated(P);
    int terminated_num = 0;
    bool flg = true;
    while (terminated_num < P and flg) {
      flg = false;
      rep(p, P) {
        if (terminated[p])
          continue;
        bool terminatable = true;
        rep(r, R) {
          if (need[p][r] > left[r]) {
            terminatable = false;
            break;
          }
        }
        if (terminatable) {
          rep(r, R) { left[r] += N[p][r]; }
          terminated[p] = true;
          terminated_num++;
          flg = true;
        }
      }
    }
    cerr << "! " << t << " " << terminated_num << endl;
    return terminated_num == P;
  }

  bool solve() {
    cin >> P >> R >> T;
    L.resize(R);
    cin >> L;
    N.resize(P, vector<int>(R));
    cin >> N;
    PR.resize(T);
    rep(i, T) {
      cin >> PR[i].first >> PR[i].second;
      PR[i].first--;
      PR[i].second--;
    }

    int l = 0, r = T + 1;
    while (l + 1 < r) {
      int m = (l + r) / 2;
      (is_avoidable(m) ? l : r) = m;
    }
    cout << (r > T ? -1 : r) << endl;
    return 0;
  }
};

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  Solver s;
  s.solve();
  return 0;
}