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

#include "bits/stdc++.h"
#include <unordered_map>
#include <unordered_set>
#pragma warning(disable : 4996)
using namespace std;
using ld = long double;
template <class T> using Table = vector<vector<T>>;
const ld eps = 1e-9;

//// < "D:\\D_Download\\Visual Studio
///2015\\Projects\\programing_contest_c++\\Debug\\a.txt"
map<char, int> mp;
int a = 0;
long long int calc(const long long int a, const char c, const long long int b) {
  if (c == '-')
    return a - b;
  else if (c == '+')
    return a + b;
  else if (c == '*')
    return a * b;
  else if (c == '|')
    return a | b;
  else if (c == '^')
    return a ^ b;
  else if (c == '&')
    return a & b;
}
long long int getnum(const string &st) {
  long long int num = 0;
  if (st[a] == '0')
    assert(false);
  while (isdigit(st[a])) {
    num = num * 10 + st[a] - '0';
    a++;
  }
  return num;
}

long long int getexpr(const string &st, const int depth) {
  if (depth == -1) {
    if (st[a] == '(') {
      a++;
      long long int num = getexpr(st, 4);
      a++;
      return num;
    }
    return getnum(st);
  }
  long long int num = getexpr(st, depth - 1);
  while (st.size() != a) {
    const char c = st[a];
    if (c == ')') {
      return num;
    }
    if (mp[c] < depth) {
      assert(false);
    } else if (mp[c] == depth) {
      a++;
      const long long int anum = getexpr(st, depth - 1);
      num = calc(num, c, anum);
    } else if (mp[c] > depth) {
      return num;
    }
  }
  return num;
}
long long int solve(const string &st) {
  a = 0;
  return getexpr(st, 4);
}
map<pair<string, pair<bool, int>>, long long int> amp;
set<char> kigous;
long long int getans(const string &st, const int rest, bool needmax);
void getnext(string st, const int rest, const int needmax, int place, char c,
             bool er, long long &amax, long long &amin) {
  if (!er) {

    st.insert(st.begin() + place, c);
  } else {
    st.erase(st.begin() + place);
  }
  long long int value = getans(st, rest - 1, !needmax);
  amax = max(amax, value);
  amin = min(amin, value);
}
long long int getans(const string &st, const int rest, bool needmax) {
  if (rest == 0) {
    long long int num = solve(st);
    return num;
  } else {
    if (amp.find(make_pair(st, make_pair(needmax, rest))) != amp.end())
      return amp[make_pair(st, make_pair(needmax, rest))];
    else {
      long long int amax = -1e18;
      long long int amin = 1e18;

      // insert
      for (int i = 0; i <= st.size(); ++i) {
        const auto it = st.begin() + i;
        if (it == st.begin()) {
          if (isdigit(*it)) {
            for (int n = 1; n <= 9; ++n) {
              getnext(st, rest, needmax, i, n + '0', false, amax, amin);
            }
          }
        } else if (it == st.end()) {
          if (isdigit(*prev(it))) {
            for (int n = 0; n <= 9; ++n) {
              getnext(st, rest, needmax, i, n + '0', false, amax, amin);
            }
          }
        } else {
          if (isdigit(*it)) {
            for (int n = 1; n <= 9; ++n) {
              getnext(st, rest, needmax, i, n + '0', false, amax, amin);
            }
            if (isdigit(*prev(it))) {
              getnext(st, rest, needmax, i, '0', false, amax, amin);

              if (*it != '0') {
                for (auto c : kigous) {
                  getnext(st, rest, needmax, i, c, false, amax, amin);
                }
              }
            }
          } else {
            if (isdigit(*prev(it))) {
              for (int n = 0; n <= 9; ++n) {
                getnext(st, rest, needmax, i, n + '0', false, amax, amin);
              }
            }
          }
        }
      }
      // erase
      for (int i = 0; i < st.size(); ++i) {
        if (st == "1+2*30-4") {
          assert(true);
          int a = 0;
          a++;
        }
        if (st[i] == '(' || st[i] == ')')
          continue;
        if (i == 0) {
          if (i + 1 < st.size()) {
            if (isdigit(st[i]) && isdigit(st[i + 1])) {
              if (st[i + 1] == '0')
                continue;
              getnext(st, rest, needmax, i, ' ', true, amax, amin);
            }
          }
        } else if (i == st.size() - 1) {
          if (0 <= i - 1) {
            if (isdigit(st[i - 1]) && isdigit(st[i])) {
              getnext(st, rest, needmax, i, ' ', true, amax, amin);
            }
          }
        } else {
          if (isdigit(st[i + 1]) || isdigit(st[i - 1])) {
            if (isdigit(st[i + 1]) && !isdigit(st[i - 1])) {
              if (st[i + 1] == '0')
                continue;
            }
            if (st[i + 1] == '(' || st[i - 1] == ')')
              continue;
            getnext(st, rest, needmax, i, ' ', true, amax, amin);
          }
        }
      }
      if (needmax)
        return amp[make_pair(st, make_pair(needmax, rest))] = amax;
      else
        return amp[make_pair(st, make_pair(needmax, rest))] = amin;
    }
  }
}
int main() {
  mp['*'] = 0;
  mp['+'] = 1;
  mp['-'] = 1;
  mp['&'] = 2;
  mp['^'] = 3;
  mp['|'] = 4;
  for (auto m : mp) {
    kigous.insert(m.first);
  }
  while (1) {

    int N;
    cin >> N;
    while (N >= 3)
      N -= 2;
    string st;
    cin >> st;
    if (st == "#")
      break;
    long long int ans = getans(st, N, true);
    // cout << amp[make_pair("1+2*30-4", 2)] << endl;
    cout << ans << endl;
  }
  return 0;
}

Error: MLE

Fixed submission:

#include "bits/stdc++.h"
#include <unordered_map>
#include <unordered_set>
#pragma warning(disable : 4996)
using namespace std;
using ld = long double;
template <class T> using Table = vector<vector<T>>;
const ld eps = 1e-9;

//// < "D:\\D_Download\\Visual Studio
///2015\\Projects\\programing_contest_c++\\Debug\\a.txt"
map<char, int> mp;
int a = 0;
long long int calc(const long long int a, const char c, const long long int b) {
  if (c == '-')
    return a - b;
  else if (c == '+')
    return a + b;
  else if (c == '*')
    return a * b;
  else if (c == '|')
    return a | b;
  else if (c == '^')
    return a ^ b;
  else if (c == '&')
    return a & b;
}
long long int getnum(const string &st) {
  long long int num = 0;
  if (st[a] == '0')
    assert(false);
  while (isdigit(st[a])) {
    num = num * 10 + st[a] - '0';
    a++;
  }
  return num;
}

long long int getexpr(const string &st, const int depth) {
  if (depth == -1) {
    if (st[a] == '(') {
      a++;
      long long int num = getexpr(st, 4);
      a++;
      return num;
    }
    return getnum(st);
  }
  long long int num = getexpr(st, depth - 1);
  while (st.size() != a) {
    const char c = st[a];
    if (c == ')') {
      return num;
    }
    if (mp[c] < depth) {
      assert(false);
    } else if (mp[c] == depth) {
      a++;
      const long long int anum = getexpr(st, depth - 1);
      num = calc(num, c, anum);
    } else if (mp[c] > depth) {
      return num;
    }
  }
  return num;
}
long long int solve(const string &st) {
  a = 0;
  return getexpr(st, 4);
}
map<pair<string, int>, long long int> amp;
set<char> kigous;
long long int getans(const string &st, const int rest, bool needmax);
void getnext(string st, const int rest, const int needmax, int place, char c,
             bool er, long long &amax, long long &amin) {
  if (!er) {

    st.insert(st.begin() + place, c);
  } else {
    st.erase(st.begin() + place);
  }
  long long int value = getans(st, rest - 1, !needmax);
  amax = max(amax, value);
  amin = min(amin, value);
}
long long int getans(const string &st, const int rest, bool needmax) {
  if (rest == 0) {
    long long int num = solve(st);
    return num;
  } else {
    if (amp.find(make_pair(st, rest)) != amp.end())
      return amp[make_pair(st, rest)];
    else {
      if (st == "1+2*30-4") {
        assert(true);
        int a = 0;
        a++;
      }
      long long int amax = -1e18;
      long long int amin = 1e18;

      // insert
      for (int i = 0; i <= st.size(); ++i) {
        const auto it = st.begin() + i;
        if (it == st.begin()) {
          if (isdigit(*it)) {
            for (int n = 1; n <= 9; ++n) {
              getnext(st, rest, needmax, i, n + '0', false, amax, amin);
            }
          }
        } else if (it == st.end()) {
          if (isdigit(*prev(it))) {
            for (int n = 0; n <= 9; ++n) {
              getnext(st, rest, needmax, i, n + '0', false, amax, amin);
            }
          }
        } else {
          if (isdigit(*it)) {
            for (int n = 1; n <= 9; ++n) {
              getnext(st, rest, needmax, i, n + '0', false, amax, amin);
            }
            if (isdigit(*prev(it))) {
              getnext(st, rest, needmax, i, '0', false, amax, amin);

              if (*it != '0') {
                for (auto c : kigous) {
                  getnext(st, rest, needmax, i, c, false, amax, amin);
                }
              }
            }
          } else {
            if (isdigit(*prev(it))) {
              for (int n = 0; n <= 9; ++n) {
                getnext(st, rest, needmax, i, n + '0', false, amax, amin);
              }
            }
          }
        }
      }
      if (st == "1+2*30-4") {
        assert(true);
        int a = 0;
        a++;
      }
      // erase
      for (int i = 0; i < st.size(); ++i) {
        if (st == "1+2*30-4") {
          assert(true);
          int a = 0;
          a++;
        }
        if (st[i] == '(' || st[i] == ')')
          continue;
        if (i == 0) {
          if (i + 1 < st.size()) {
            if (isdigit(st[i]) && isdigit(st[i + 1])) {
              if (st[i + 1] == '0')
                continue;
              getnext(st, rest, needmax, i, ' ', true, amax, amin);
            }
          }
        } else if (i == st.size() - 1) {
          if (0 <= i - 1) {
            if (isdigit(st[i - 1]) && isdigit(st[i])) {
              getnext(st, rest, needmax, i, ' ', true, amax, amin);
            }
          }
        } else {
          if (isdigit(st[i + 1]) || isdigit(st[i - 1])) {
            if (isdigit(st[i + 1]) && !isdigit(st[i - 1])) {
              if (st[i + 1] == '0')
                continue;
            }
            if (st[i + 1] == '(' || st[i - 1] == ')')
              continue;
            getnext(st, rest, needmax, i, ' ', true, amax, amin);
          }
        }
      }
      if (needmax)
        return amp[make_pair(st, rest)] = amax;
      else
        return amp[make_pair(st, rest)] = amin;
    }
  }
}
int main() {
  mp['*'] = 0;
  mp['+'] = 1;
  mp['-'] = 1;
  mp['&'] = 2;
  mp['^'] = 3;
  mp['|'] = 4;
  for (auto m : mp) {
    kigous.insert(m.first);
  }
  while (1) {

    int N;
    cin >> N;
    while (N >= 5)
      N -= 2;
    string st;
    cin >> st;
    if (st == "#")
      break;
    long long int ans = getans(st, N, true);
    // cout << amp[make_pair("1+2*30-4", 2)] << endl;
    cout << ans << endl;
  }
  return 0;
}