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

#include <cctype>
#include <cstdio>
#include <map>
#include <set>
#include <string>
#include <vector>

struct directive {
  char type;
  std::string dst, src1, src2;
  size_t dline;
  directive() = default;
  directive(std::string const &, std::string const &dst, std::string const &src)
      : type('='), dst(dst), src1(src) {}
  directive(std::string const &dir, std::string const &dst,
            std::string const &src1, std::string const &src2)
      : type((dir[0] == 'A') ? '+' : '-'), dst(dst), src1(src1), src2(src2) {}
  directive(std::string const &, std::string const &cond, size_t dline)
      : type('?'), src1(cond), dline(dline) {}
  directive(std::string const &) : type('q') {}

  size_t operator()(std::map<size_t, size_t> &nl, std::map<char, int> &var,
                    size_t i) {
    ++i;
    if (type == '+') {
      int tmp =
          var[src1[0]] + (isdigit(src2[0]) ? std::stoi(src2) : var[src2[0]]);
      if (!(0 <= tmp && tmp < 16))
        throw 1;
      var[dst[0]] = tmp;
    } else if (type == '-') {
      int tmp =
          var[src1[0]] - (isdigit(src2[0]) ? std::stoi(src2) : var[src2[0]]);
      if (!(0 <= tmp && tmp < 16))
        throw 1;
      var[dst[0]] = tmp;
    } else if (type == '=') {
      int tmp = (isdigit(src1[0]) ? std::stoi(src1) : var[src1[0]]);
      if (!(0 <= tmp && tmp < 16))
        throw 1;
      var[dst[0]] = tmp;
    } else if (type == '?') {
      if (var[src1[0]]) {
        auto it = nl.find(dline);
        if (it == nl.end())
          throw 2;
        i = it->second;
      }
    } else if (type == 'q') {
      throw 0;
    }
    return i;
  }
};

int encode(std::map<char, int> const &map) {
  int res = 0;
  for (auto const &p : map)
    res = (res << 4) | p.second;
  return res;
}

int main() {
  size_t n;
  scanf("%zu", &n);

  std::vector<directive> prog;
  std::map<size_t, size_t> nl;
  std::map<char, int> var;

  for (size_t i = 0; i < n; ++i) {
    size_t line;
    scanf("%zu", &line);
    nl[line] = i;

    char buf[16];
    scanf("%s", buf);
    std::string s = buf;
    if (s == "SET") {
      scanf("%s", buf);
      std::string dst = buf;
      scanf("%s", buf);
      std::string src = buf;
      var[dst[0]];
      if (isalpha(src[0]))
        var[src[0]];
      prog.emplace_back("SET", dst, src);
    } else if (s == "ADD" || s == "SUB") {
      scanf("%s", buf);
      std::string dst = buf;
      scanf("%s", buf);
      std::string src1 = buf;
      scanf("%s", buf);
      std::string src2 = buf;
      var[dst[0]];
      var[src1[0]];
      if (isalpha(src2[0]))
        var[src2[0]];
      prog.emplace_back(s, dst, src1, src2);
    } else if (s == "IF") {
      scanf("%s", buf);
      std::string cond = buf;
      size_t dst;
      scanf("%zu", &dst);
      var[cond[0]];
      prog.emplace_back("IF", cond, dst);
    } else if (s == "HALT") {
      prog.emplace_back("HALT");
    }
  }

  size_t i = 0;
  std::vector<bool> tsurai(50 * 16 * 16 * 16 * 16 * 16);
  tsurai[encode(var) * 50 + i] = true;
  while (i < n) {
    try {
      size_t j = prog[i](nl, var, i);
      i = j;
    } catch (int e) {
      break;
    }

    int e = encode(var);
    if (tsurai[e * 50 + i])
      return puts("inf"), 0;
    tsurai[e * 50 + i] = true;
  }
  for (auto const &p : var)
    printf("%c=%d\\n", p.first, p.second);
}


Error: MLE

Fixed submission:

#include <cctype>
#include <cstdio>
#include <map>
#include <set>
#include <string>
#include <vector>

struct directive {
  char type;
  std::string dst, src1, src2;
  size_t dline;
  directive() = default;
  directive(std::string const &, std::string const &dst, std::string const &src)
      : type('='), dst(dst), src1(src) {}
  directive(std::string const &dir, std::string const &dst,
            std::string const &src1, std::string const &src2)
      : type((dir[0] == 'A') ? '+' : '-'), dst(dst), src1(src1), src2(src2) {}
  directive(std::string const &, std::string const &cond, size_t dline)
      : type('?'), src1(cond), dline(dline) {}
  directive(std::string const &) : type('q') {}

  size_t operator()(std::map<size_t, size_t> &nl, std::map<char, int> &var,
                    size_t i) {
    ++i;
    if (type == '+') {
      int tmp =
          var[src1[0]] + (isdigit(src2[0]) ? std::stoi(src2) : var[src2[0]]);
      if (!(0 <= tmp && tmp < 16))
        throw 1;
      var[dst[0]] = tmp;
    } else if (type == '-') {
      int tmp =
          var[src1[0]] - (isdigit(src2[0]) ? std::stoi(src2) : var[src2[0]]);
      if (!(0 <= tmp && tmp < 16))
        throw 1;
      var[dst[0]] = tmp;
    } else if (type == '=') {
      int tmp = (isdigit(src1[0]) ? std::stoi(src1) : var[src1[0]]);
      if (!(0 <= tmp && tmp < 16))
        throw 1;
      var[dst[0]] = tmp;
    } else if (type == '?') {
      if (var[src1[0]]) {
        auto it = nl.find(dline);
        if (it == nl.end())
          throw 2;
        i = it->second;
      }
    } else if (type == 'q') {
      throw 0;
    }
    return i;
  }
};

int encode(std::map<char, int> const &map) {
  int res = 0;
  for (auto const &p : map)
    res = (res << 4) | p.second;
  return res;
}

int main() {
  size_t n;
  scanf("%zu", &n);

  std::vector<directive> prog;
  std::map<size_t, size_t> nl;
  std::map<char, int> var;

  for (size_t i = 0; i < n; ++i) {
    size_t line;
    scanf("%zu", &line);
    nl[line] = i;

    char buf[16];
    scanf("%s", buf);
    std::string s = buf;
    if (s == "SET") {
      scanf("%s", buf);
      std::string dst = buf;
      scanf("%s", buf);
      std::string src = buf;
      var[dst[0]];
      if (isalpha(src[0]))
        var[src[0]];
      prog.emplace_back("SET", dst, src);
    } else if (s == "ADD" || s == "SUB") {
      scanf("%s", buf);
      std::string dst = buf;
      scanf("%s", buf);
      std::string src1 = buf;
      scanf("%s", buf);
      std::string src2 = buf;
      var[dst[0]];
      var[src1[0]];
      if (isalpha(src2[0]))
        var[src2[0]];
      prog.emplace_back(s, dst, src1, src2);
    } else if (s == "IF") {
      scanf("%s", buf);
      std::string cond = buf;
      size_t dst;
      scanf("%zu", &dst);
      var[cond[0]];
      prog.emplace_back("IF", cond, dst);
    } else if (s == "HALT") {
      prog.emplace_back("HALT");
    }
  }

  size_t i = 0;
  std::set<std::pair<size_t, int>> memo;
  memo.emplace(i, encode(var));
  while (i < n) {
    try {
      size_t j = prog[i](nl, var, i);
      i = j;
    } catch (int e) {
      break;
    }

    int e = encode(var);
    if (memo.count(std::make_pair(i, e)))
      return puts("inf"), 0;
    memo.emplace(i, e);
  }
  for (auto const &p : var)
    printf("%c=%d\\n", p.first, p.second);
}