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

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

const ll INF = 1LL << 60;

struct Parser {
  string s;
  int N;
  int c;

  ll parse(string s) {
    this->s = s;
    N = s.size();
    c = 0;
    try {
      ll ret = or_term();
      if (c != N)
        throw "";
      return ret;
    } catch (...) {
      // cout << s << endl;
      return INF;
    }
  }

  void debug(string text) {
    return;
    cout << text + " ";
    for (int i = 0; i < N; i++) {
      if (i == c)
        cout << '[' << s[i] << ']';
      else
        cout << s[i];
    }
    cout << endl;
  }

  ll or_term() {
    debug("or_term");
    ll x = xor_term();
    while (c < N) {
      if (s[c] == '|') {
        c++;
        x |= xor_term();
      } else
        break;
    }
    return x;
  }

  ll xor_term() {
    debug("xor_term");
    ll x = and_term();
    while (c < N) {
      if (s[c] == '^') {
        c++;
        x ^= and_term();
      } else
        break;
    }
    return x;
  }

  ll and_term() {
    debug("and_term");
    ll x = expr();
    while (c < N) {
      if (s[c] == '&') {
        c++;
        x &= expr();
      } else
        break;
    }
    return x;
  }

  ll expr() {
    debug("expr");
    ll x = term();
    while (c < N) {
      if (s[c] == '+') {
        c++;
        x += term();
      } else if (s[c] == '-') {
        c++;
        x -= term();
      } else
        break;
    }
    return x;
  }

  ll term() {
    debug("term");
    ll x = factor();
    while (c < N) {
      if (s[c] == '*') {
        c++;
        x *= factor();
      } else
        break;
    }
    return x;
  }

  ll factor() {
    debug("factor");
    if (s[c] == '(') {
      c++;
      ll ret = or_term();
      if (s[c] != ')')
        throw "";
      // assert(s[c] == ')');
      c++;
      return ret;
    }
    return num();
  }

  ll num() {
    debug("num");
    if (s[c] == '0' || !isdigit(s[c]))
      throw "";
    ll ret = 0;
    while (c < N && isdigit(s[c])) {
      ret = ret * 10 + s[c] - '0';
      c++;
    }
    return ret;
  }
};

int M;
Parser p;

ll f(string t, int turn, int n) {
  if (n == M) {
    return p.parse(t);
  }

  ll ret = turn == 0 ? -1e18 : 1e18;
  string cs = "0123456789*+-|^&";
  for (int i = 0; i < t.size() + 1; i++) {
    for (auto c : cs) {
      string tt = t;
      tt.insert(tt.begin() + i, c);
      ll res = f(tt, 1 - turn, n + 1);
      if (p.parse(tt) == INF)
        continue;
      if (turn == 0) {
        // cout << tt << " " << res << endl;
        ret = max(ret, res);
      } else {
        ret = min(ret, res);
      }
    }
  }
  if (t.size() >= 2) {
    for (int i = 0; i < t.size(); i++) {
      string tt = t;
      tt.erase(tt.begin() + i);
      ll res = f(tt, 1 - turn, n + 1);
      if (p.parse(tt) == INF)
        continue;
      if (turn == 0) {
        // cout << tt << " " << res << endl;
        ret = max(ret, res);
      } else {
        ret = min(ret, res);
      }
    }
  }
  return ret;
}

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
#ifdef LOCAL
  std::ifstream in("in");
  std::cin.rdbuf(in.rdbuf());
#endif

  string t;
  while (cin >> M >> t, M) {
    M = M % 2 ? 1 : 2;
    cout << f(t, 0, 0) << endl;
  }
}

Error: 0

Fixed submission:

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

string s;
int N;
int c;

ll expr();
ll or_term();
ll xor_term();
ll and_term();
ll term();
ll factor();
ll num();

void debug(string text) {
  return;
  cout << text + " ";
  for (int i = 0; i < N; i++) {
    if (i == c)
      cout << '[' << s[i] << ']';
    else
      cout << s[i];
  }
  cout << endl;
}

ll or_term() {
  debug("or_term");
  ll x = xor_term();
  while (c < N) {
    if (s[c] == '|') {
      c++;
      x |= xor_term();
    } else
      break;
  }
  return x;
}

ll xor_term() {
  debug("xor_term");
  ll x = and_term();
  while (c < N) {
    if (s[c] == '^') {
      c++;
      x ^= and_term();
    } else
      break;
  }
  return x;
}

ll and_term() {
  debug("and_term");
  ll x = expr();
  while (c < N) {
    if (s[c] == '&') {
      c++;
      x &= expr();
    } else
      break;
  }
  return x;
}

ll expr() {
  debug("expr");
  ll x = term();
  while (c < N) {
    if (s[c] == '+') {
      c++;
      x += term();
    } else if (s[c] == '-') {
      c++;
      x -= term();
    } else
      break;
  }
  return x;
}

ll term() {
  debug("term");
  ll x = factor();
  while (c < N) {
    if (s[c] == '*') {
      c++;
      x *= factor();
    } else
      break;
  }
  return x;
}

ll factor() {
  debug("factor");
  if (s[c] == '(') {
    c++;
    ll ret = or_term();
    assert(s[c] == ')');
    c++;
    return ret;
  }
  return num();
}

ll num() {
  debug("num");
  ll ret = 0;
  while (c < N && isdigit(s[c])) {
    ret = ret * 10 + s[c] - '0';
    c++;
  }
  return ret;
}

int M;

bool check(string s) {
  for (int i = 0; i < s.size() - 1; i++) {
    if (!isdigit(s[i]) && isdigit(s[i + 1]) && s[i + 1] == '0')
      return false;
  }
  return true;
}

ll f(string t, int turn, int n) {
  if (n == M) {
    s = t;
    N = s.size();
    c = 0;
    return or_term();
  }

  ll ret = turn == 0 ? -1e18 : 1e18;
  set<char> op({'*', '+', '-', '|', '^', '&'});
  for (int i = 0; i < t.size() + 1; i++) {
    if (i - 1 >= 0 && isdigit(t[i - 1]) || i < t.size() && isdigit(t[i])) {
      for (int j = 0; j < 10; j++) {
        string tt = t;
        tt.insert(tt.begin() + i, char('0' + j));
        if (check(tt)) {
          ll res = f(tt, 1 - turn, n + 1);
          if (turn == 0) {
            ret = max(ret, res);
          } else {
            ret = min(ret, res);
          }
        }
      }
    }
    if (i - 1 >= 0 && isdigit(t[i - 1]) && i < t.size() && isdigit(t[i])) {
      for (auto o : op) {
        string tt = t;
        tt.insert(tt.begin() + i, o);
        if (check(tt)) {
          ll res = f(tt, 1 - turn, n + 1);
          if (turn == 0) {
            ret = max(ret, res);
          } else {
            ret = min(ret, res);
          }
        }
      }
    }
  }
  for (int i = 0; i < t.size(); i++) {
    if (op.count(t[i])) {
      string tt = t;
      tt.erase(tt.begin() + i);
      if (check(tt)) {
        ll res = f(tt, 1 - turn, n + 1);
        if (turn == 0) {
          ret = max(ret, res);
        } else {
          ret = min(ret, res);
        }
      }
    } else if (isdigit(t[i])) {
      if (i - 1 >= 0 && isdigit(t[i - 1]) ||
          i + 1 < t.size() && isdigit(t[i + 1])) {
        string tt = t;
        tt.erase(tt.begin() + i);
        if (check(tt)) {
          ll res = f(tt, 1 - turn, n + 1);
          if (turn == 0) {
            ret = max(ret, res);
          } else {
            ret = min(ret, res);
          }
        }
      }
    }
  }
  return ret;
}

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
#ifdef LOCAL
  std::ifstream in("in");
  std::cin.rdbuf(in.rdbuf());
#endif

  string t;
  while (cin >> M >> t, M) {
    M = M % 2 ? 1 : 2;
    cout << f(t, 0, 0) << endl;
  }
}