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

#include <algorithm>
#include <array>
#include <cassert>
#include <climits>
#include <complex>
#include <cstdio>
#include <cstring>
#include <functional>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <string>
#include <tuple>
#include <vector>

using namespace std;
#define REP(i, n) for (int i = 0; i < (int)(n); i++)
#define ALL(x) (x).begin(), (x).end()

#define int long long
#define vi vector<int>
#define vvi vector<vector<int>>
#define rt tuple<int, bool>

int c = -1;
string e;
bool p = false;

int expr();

int dig() {
  if (!(isdigit(e[c]) && e[c] != '0')) {
    p = true;
    return -1;
  }
  int res = 0;
  while (isdigit(e[c])) {
    res *= 10;
    res += e[c] - '0';
    c++;
  }
  return res;
}
int term6() {
  if (e[c] == '(') {
    c++;
    int res = expr();
    if (e[c] != ')') {
      p = true;
    }
    c++;
    return res;
  }
  int res = dig();
  return res;
}
int term5() {
  if (p)
    return -1;
  int res = term6();
  while (e[c] == '*') {
    c++;
    res *= term6();
  }
  return res;
}
int term4() {
  if (p)
    return -1;
  int res = term5();
  while (e[c] == '-' || e[c] == '+') {
    if (e[c] == '-') {
      c++;
      res -= term5();
    }
    if (e[c] == '+') {
      c++;
      res += term5();
    }
  }
  return res;
}
int term3() {
  if (p)
    return -1;
  int res = term4();
  while (e[c] == '&') {
    c++;
    res &= term4();
  }
  return res;
}
int term2() {
  if (p)
    return -1;
  int res = term3();
  while (e[c] == '^') {
    c++;
    res ^= term3();
  }
  return res;
}
int term1() {
  if (p)
    return -1;
  int res = term2();
  while (e[c] == '|') {
    c++;
    res |= term2();
  }
  return res;
}
int expr() {
  if (p)
    return -1;
  int res = term1();
  return res;
}

tuple<bool, int> calc(const string &exp) {
  if (exp == "")
    return make_tuple(false, -1);
  c = 0;
  e = exp + "$";
  p = false;
  int res = expr();
  if (e[c] != '$')
    p = true;
  return make_tuple(not p, res);
}

int inf = 9123456789123456789;
int ab(const string &exp, int depth, bool mn) {
  if (depth == 0) { /*cout << " " << exp << "=" << endl;*/
    return get<1>(calc(exp));
  }
  vector<string> couh;
  int res = -inf;
  if (mn)
    res = inf;
  auto upd = [&](const string &&r) {
    if (get<0>(calc(r))) {
      int ks = ab(r, depth - 1, not mn);
      // cout<<r<<":="<<ks<<endl;
      if (mn) {
        res = min(res, ks);
      } else {
        res = max(res, ks);
      }
    }
    return false;
  };
  [&] {
    REP(i, exp.size()) {
      bool r =
          upd(string(exp.substr(0, i) + exp.substr(i + 1, exp.size() - i + 1)));
      if (r)
        return;
    }
    string ops = "9*+-&|^876543210";
    REP(i, exp.size() + 1) {
      REP(k, ops.size()) {
        bool r = upd(string(exp.substr(0, i) + ops[k] +
                            exp.substr(i, exp.size() - i + 1)));
        if (r)
          return;
      }
    }
  }();
  // cout << depth << ":" << exp << "#" << res << endl;
  return res;
}
signed main() {
  while (true) {
    int n;
    string s;
    cin >> n >> s;
    if (n == 0)
      break;
    int k = n % 2;
    if (k == 0)
      k = 2;
    cout << ab(s, k, false) << endl;
  }
}


Error: TLE

Fixed submission:

#include <algorithm>
#include <array>
#include <cassert>
#include <climits>
#include <complex>
#include <cstdio>
#include <cstring>
#include <functional>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <string>
#include <tuple>
#include <vector>

using namespace std;
#define REP(i, n) for (int i = 0; i < (int)(n); i++)
#define ALL(x) (x).begin(), (x).end()

#define int long long
#define vi vector<int>
#define vvi vector<vector<int>>
#define rt tuple<int, bool>

int c = -1;
string e;
bool p = false;

int expr();

int dig() {
  if (!(isdigit(e[c]) && e[c] != '0')) {
    p = true;
    return -1;
  }
  int res = 0;
  while (isdigit(e[c])) {
    res *= 10;
    res += e[c] - '0';
    c++;
  }
  return res;
}
int term6() {
  if (e[c] == '(') {
    c++;
    int res = expr();
    if (e[c] != ')') {
      p = true;
    }
    c++;
    return res;
  }
  int res = dig();
  return res;
}
int term5() {
  if (p)
    return -1;
  int res = term6();
  while (e[c] == '*') {
    c++;
    res *= term6();
  }
  return res;
}
int term4() {
  if (p)
    return -1;
  int res = term5();
  while (e[c] == '-' || e[c] == '+') {
    if (e[c] == '-') {
      c++;
      res -= term5();
    }
    if (e[c] == '+') {
      c++;
      res += term5();
    }
  }
  return res;
}
int term3() {
  if (p)
    return -1;
  int res = term4();
  while (e[c] == '&') {
    c++;
    res &= term4();
  }
  return res;
}
int term2() {
  if (p)
    return -1;
  int res = term3();
  while (e[c] == '^') {
    c++;
    res ^= term3();
  }
  return res;
}
int term1() {
  if (p)
    return -1;
  int res = term2();
  while (e[c] == '|') {
    c++;
    res |= term2();
  }
  return res;
}
int expr() {
  if (p)
    return -1;
  int res = term1();
  return res;
}

tuple<bool, int> calc(const string &exp) {
  if (exp == "")
    return make_tuple(false, -1);
  c = 0;
  e = exp + "$";
  p = false;
  int res = expr();
  if (e[c] != '$')
    p = true;
  return make_tuple(not p, res);
}

int inf = 9123456789123456789;
int ab(const string &exp, int depth, bool mn, int al, int ar) {
  if (depth == 0)
    return get<1>(calc(exp));
  vector<string> couh;
  auto upd = [&](const string &&r) {
    if (get<0>(calc(r))) {
      int ks = ab(r, depth - 1, not mn, al, ar);
      if (mn) {
        ar = min(ar, ks);
      } else {
        al = max(al, ks);
      }
      if (ar <= al)
        return true;
    }
    return false;
  };
  [&] {
    REP(i, exp.size()) {
      bool r =
          upd(string(exp.substr(0, i) + exp.substr(i + 1, exp.size() - i + 1)));
      if (r)
        return;
    }
    string ops = "*+-&|^9876543210";
    REP(i, exp.size() + 1) {
      REP(k, ops.size()) {
        bool r = upd(string(exp.substr(0, i) + ops[k] +
                            exp.substr(i, exp.size() - i + 1)));
        if (r)
          return;
      }
    }
  }();
  // REP(k, 5 - depth) cout << "-"
  // cout << "# " << res << endl;
  if (mn)
    return ar;
  return al;
}
signed main() {
  while (true) {
    int n;
    string s;
    cin >> n >> s;
    if (n == 0)
      break;
    cout << ab(s, n, false, -inf, +inf) << endl;
  }
}