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

#include <bits/stdc++.h>
#define GET_MACRO(_1, _2, _3, _4, _5, _6, NAME, ...) NAME
#define pr(...)                                                                \\
  GET_MACRO(__VA_ARGS__, pr6, pr5, pr4, pr3, pr2, pr1)(__VA_ARGS__)
#define Pr(a) (#a) << "=" << (a) << " "
#define pr1(a) cerr << Pr(a) << endl;
#define pr2(a, b) cerr << Pr(a) << Pr(b) << endl;
#define pr3(a, b, c) cerr << Pr(a) << Pr(b) << Pr(c) << endl;
#define pr4(a, b, c, d) cerr << Pr(a) << Pr(b) << Pr(c) << Pr(d) << endl;
#define pr5(a, b, c, d, e)                                                     \\
  cerr << Pr(a) << Pr(b) << Pr(c) << Pr(d) << Pr(e) << endl;
#define pr6(a, b, c, d, e, f)                                                  \\
  cerr << Pr(a) << Pr(b) << Pr(c) << Pr(d) << Pr(e) << Pr(f) << endl;
#define int long long
#define double long double
using namespace std;
const int INF = 1LL << 60;
const int mod = (1e9) + 7;
const double EPS = 1e-8;
const double PI = 6.0 * asin(0.5);
typedef pair<int, int> P;
typedef long long ll;
template <class T> T Max(T &a, T b) { return a = max(a, b); }
template <class T> T Min(T &a, T b) { return a = min(a, b); }
ostream &operator<<(ostream &o, P p) {
  return o << "(" << p.first << "," << p.second << ")";
}
istream &operator>>(istream &i, P &p) { return i >> p.first >> p.second; }
ostream &operator<<(ostream &o, vector<auto> &a) {
  int i = 0;
  for (auto t : a)
    o << (i++ ? " " : "") << t;
  return o;
}
istream &operator>>(istream &i, vector<auto> &a) {
  for (auto &t : a)
    i >> t;
  return i;
}
void prArr(auto a, string s = " ") {
  int i = 0;
  for (auto t : a)
    cout << (i++ ? s : "") << t;
  cout << endl;
}

typedef vector<int> V;
typedef vector<V> VV;
class Len {
public:
  string str;
  VV mem, used;

  Len() {}
  Len(string str) : str(str), mem(2010, V(2010, 0)), used(2010, V(2010, 0)) {
    dfs(0, str.size() - 1);
  }

  int dfs(int l, int r) {
    if (l == r)
      return 1;
    if (l > r)
      return 0;
    if (used[l][r]++)
      return mem[l][r];

    int res = INF;
    if (str[l] == str[r])
      res = 2 + dfs(l + 1, r - 1);
    Min(res, 2 + dfs(l + 1, r));
    Min(res, 2 + dfs(l, r - 1));
    return mem[l][r] = res;
  }
};

class Cnt {
public:
  string str;
  Len len;
  VV mem, used;
  Cnt() {}
  Cnt(string str)
      : str(str), len(str), mem(2010, V(2010, 0)), used(2010, V(2010, 0)) {
    dfs(0, str.size() - 1);
    used = VV(2010, V(2010, 1));
  }

  int dfs(int l, int r) { //[l,r]
    if (l >= r)
      return 1;
    if (used[l][r]++)
      return mem[l][r];

    int mn = len.dfs(l, r);
    int a = 0, b = 0, c = 0;
    if (str[l] == str[r] && mn == len.dfs(l + 1, r - 1) + 2)
      a = dfs(l + 1, r - 1);
    else {
      if (mn == len.dfs(l + 1, r) + 2)
        b = dfs(l + 1, r);
      if (mn == len.dfs(l, r - 1) + 2)
        c = dfs(l, r - 1);
    }
    int res = min(INF, a + min(INF, b + c));
    return mem[l][r] = res;
  }
};

string str;
Cnt cnt;
string ans;
void dfs(int l, int r, int K) {
  if (l == r) {
    ans += str[l];
    return;
  }
  if (l > r)
    return;
  int mn = cnt.len.dfs(l, r);

  auto add = [](char ch) { ans += ch; };

  auto A = [&]() {
    if (K <= 0)
      return;
    int a = cnt.dfs(l + 1, r - 1);
    if (a >= K)
      add(str[l]), dfs(l + 1, r - 1, K), add(str[l]);
    K -= a;
  };

  auto B = [&]() {
    if (K <= 0)
      return;
    if (mn != cnt.len.dfs(l + 1, r) + 2)
      return;

    int a = cnt.dfs(l + 1, r);
    if (a >= K)
      add(str[l]), dfs(l + 1, r, K), add(str[l]);
    K -= a;
  };

  auto C = [&]() {
    if (K <= 0)
      return;
    if (mn != cnt.len.dfs(l, r - 1) + 2)
      return;
    int a = cnt.dfs(l, r - 1);
    if (a >= K)
      add(str[r]), dfs(l, r - 1, K), add(str[r]);
    K -= a;
  };

  if (str[l] == str[r])
    A();
  if (str[l] < str[r])
    B(), C();
  if (str[l] > str[r])
    C(), B();
}

signed main() {
  cin.tie(0);
  ios_base::sync_with_stdio(0);
  cout << fixed << setprecision(12);
  int K;
  cin >> str >> K;
  cnt = Cnt(str);
  int n = str.size();
  if (cnt.dfs(0, n - 1) < K) {
    cout << "NONE" << endl;
    return 0;
  }

  dfs(0, n - 1, K);
  assert((int)ans.size() == cnt.len.dfs(0, n - 1));
  cout << ans << endl;
  return 0;
}


Error: -6
terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc


Fixed submission:

#include <bits/stdc++.h>
#define int long long
#define double long double
using namespace std;
const int N = 100010;
const int INF = 1LL << 55;
const int mod = (1e9) + 7;
const double EPS = 1e-8;
const double PI = 6.0 * asin(0.5);
typedef long long ll;
template <class T> T Max(T &a, T b) { return a = max(a, b); }
template <class T> T Min(T &a, T b) { return a = min(a, b); }

signed main() {

  int p, r, t;
  cin >> p >> r >> t;

  vector<int> LL(r);
  for (int i = 0; i < r; i++)
    cin >> LL[i];

  vector<vector<int>> n(p, vector<int>(r));
  for (int i = 0; i < p; i++)
    for (int j = 0; j < r; j++)
      cin >> n[i][j];

  vector<int> P(t), R(t);
  for (int i = 0; i < t; i++)
    cin >> P[i] >> R[i], P[i]--, R[i]--;

  auto deadLock = [&](int x) {
    vector<int> L = LL;
    vector<queue<int>> Q(r);
    vector<vector<int>> cnt(p, vector<int>(r, 0));

    auto ok = [&](int p) {
      for (int i = 0; i < r; i++)
        if (n[p][i] != cnt[p][i])
          return 0;
      return 1;
    };

    auto freeL = [&](int p) {
      for (int i = 0; i < r; i++)
        L[i] += cnt[p][i], cnt[p][i] = 0;
    };

    auto use = [&]() {
      int res = 0;
      for (int i = 0; i < r; i++) {
        if (Q[i].empty())
          continue;
        if (L[i] == 0)
          continue;
        int process = Q[i].front();
        Q[i].pop();
        L[i]--, cnt[process][i]++;
        if (!ok(process))
          continue;
        freeL(process);
        res = 1;
      }
      return res;
    };

    for (int i = 0; i < x; i++) {
      int pi = P[i];
      int ri = R[i];
      Q[ri].push(pi);
      while (use())
        ;
    }

    auto sum = [&](int p) {
      int res = 0;
      for (int i = 0; i < r; i++)
        res += cnt[p][i];
      return res;
    };

    auto canFree = [&](int p) {
      for (int i = 0; i < r; i++)
        if (n[p][i] - cnt[p][i] > L[i])
          return 0;
      return 1;
    };

    int update = 1;
    while (update) {
      update = 0;
      for (int i = 0; i < p; i++) { // process
        if (sum(i) == 0) {
          continue;
        }
        if (!canFree(i))
          continue;
        update = 1;
        freeL(i);
        while (use())
          ;
      }
    }

    for (int i = 0; i < p; i++)
      if (sum(i))
        return 1;
    for (int i = 0; i < r; i++)
      if (!Q[i].empty())
        return 1;
    return 0;
  };

  int ans = -1;
  {
    int L = 1, R = t + 1;
    while (L + 1 < R) {
      int M = (L + R) / 2;
      if (deadLock(M))
        R = M;
      else
        L = M;
    }
    ans = R;
    if (R == t + 1)
      ans = -1;
  }

  cout << ans << endl;

  return 0;
}