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

#include <bits/stdc++.h>
#define ms(x, y) memset(x, y, sizeof(x))
using namespace std;
const int N = 305;
const int T = 200005;

int pn, rn, tn;
int tp[T], tr[T];
bool ter[N];
int untercnt = 0;
int res[N], need[N][N], req[N][N];
int tmpres[N], tmpneed[N][N];
bool tmpter[N];

bool terminate(int pi) {
  for (int j = 1; j <= rn; j++)
    if (need[pi][j])
      return false;
  return true;
}

bool canter(int pi) {
  for (int j = 1; j <= rn; j++)
    if (tmpneed[pi][j] > tmpres[j])
      return false;
  return true;
}
queue<int> q;
bool check() {
  memcpy(tmpres, res, sizeof(res));
  memcpy(tmpneed, need, sizeof(need));
  memcpy(tmpter, ter, sizeof(ter));

  int cnt = 0;
  while (!q.empty())
    q.pop();
  for (int i = 1; i <= pn; i++)
    if (!tmpter[i])
      if (canter(i))
        q.push(i);
  while (!q.empty()) {
    while (!q.empty()) {
      int now = q.front();
      q.pop();
      cnt++;
      tmpter[now] = true;
      for (int j = 1; j <= rn; j++)
        tmpres[j] += req[now][j] - need[now][j];
    }
    for (int i = 1; i <= pn; i++)
      if (!tmpter[i])
        if (canter(i))
          q.push(i);
  }
  if (cnt < untercnt)
    return false;
  return true;
}

void goup(int now, int tt) {
  for (int t = now; t > tt; t--) {
    if (ter[tp[t]])
      continue;
    res[tr[t]]++;
    need[tp[t]][tr[t]]++;
  }
}
void godown(int now, int tt) {
  for (int t = now + 1; t <= tt; t++) {
    if (ter[tp[t]])
      continue;
    res[tr[t]]--;
    need[tp[t]][tr[t]]--;
  }
}

int main() {
  scanf("%d%d%d", &pn, &rn, &tn);
  untercnt = pn;
  for (int i = 1; i <= rn; i++)
    scanf("%d", &res[i]);
  for (int i = 1; i <= pn; i++)
    for (int j = 1; j <= rn; j++) {
      scanf("%d", &req[i][j]);
      if (req[i][j] > res[j]) {
        printf("0\\n");
        return 0;
      }
      need[i][j] = req[i][j];
    }
  ms(ter, 0);
  for (int i = 1; i <= tn; i++) {
    scanf("%d%d", &tp[i], &tr[i]);
    need[tp[i]][tr[i]]--;
    res[tr[i]]--;
    if (terminate(tp[i])) {
      ter[tp[i]] = true;
      untercnt--;
      for (int j = 1; j <= rn; j++)
        res[j] += req[tp[i]][j];
    }
  }
  if (check()) {
    printf("-1\\n");
    return 0;
  }
  int l = 0, r = tn, now = tn;
  while (l < r) {
    int mid = (l + r) / 2;
    if (mid < now)
      goup(now, mid);
    else if (mid > now)
      godown(now, mid);
    now = mid;
    if (check())
      l = mid + 1;
    else
      r = mid;
  }
  printf("%d\\n", l);
  return 0;
}

Error: TLE

Fixed submission:

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

typedef pair<int, int> pii;
#define x first
#define y second
#define pb push_back
#define mp make_pair
const int maxN = 333;
const int maxO = 2e5 + 100;
int n, m, t, l[maxN], rec2[maxN];
int nd[maxN][maxN], rec[maxN][maxN];
bool li[maxN];
pii ope[maxO];

bool deadlock(int w) {
  memcpy(rec, nd, sizeof nd);
  memcpy(rec2, l, sizeof l);
  memset(li, false, sizeof li);
  for (int i = 1; i <= w; ++i) {
    nd[ope[i].x][ope[i].y]--;
    l[ope[i].y]--;
  }
  for (int p = 1; p <= n; ++p)
    for (int i = 1; i <= n; ++i) {
      if (li[i])
        break;
      bool ok = true;
      for (int k = 1; k <= m; ++k)
        if (l[k] < nd[i][k]) {
          ok = false;
          break;
        }
      if (ok) {
        for (int k = 1; k <= m; ++k)
          l[k] += rec[i][k] - nd[i][k];
        li[i] = true;
      }
    }
  memcpy(nd, rec, sizeof rec);
  memcpy(l, rec2, sizeof rec2);
  for (int i = 1; i <= n; ++i)
    if (!li[i])
      return true;
  return false;
}

int main() {
#ifdef lol
  freopen("F.in", "r", stdin);
  freopen("F.out", "w", stdout);
#endif

  scanf("%d %d %d", &n, &m, &t);
  for (int i = 1; i <= m; ++i)
    scanf("%d", &l[i]);
  for (int i = 1; i <= n; ++i)
    for (int j = 1; j <= m; ++j)
      scanf("%d", &nd[i][j]);
  for (int i = 1; i <= t; ++i)
    scanf("%d %d", &ope[i].x, &ope[i].y);
  for (int i = t; 0 < i; --i)
    if (!deadlock(i)) {
      if (i == 1) {
        puts("-1");
      } else {
        printf("%d\\n", i + 1);
      }
      exit(0);
    }
  int l = 1, r = t;
  // for (int i = 1; i <= t; ++i)
  //	printf("%d", deadlock(i));
  // puts("");
  while (l != r) {
    //	printf("%d %d\\n", l, r);
    int mid = (l + r) >> 1;
    if (!deadlock(mid))
      l = mid + 1;
    else
      r = mid;
  }
  printf("%d\\n", l >= t ? -1 : l);

  return 0;
}