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

#include <algorithm>
#include <cassert>
#include <iostream>
#include <set>
#include <string>
#include <vector>
using namespace std;
#define int long long
typedef pair<bool, int> P;

string letters = "01+-*()=";
string s;

class Equation {
  string s;

public:
  void init(string s) { this->s = s; }

  //[l, r)
  bool Q(int l, int r) {
    int i;
    int cnt = 0;
    for (i = l; i < r; i++)
      cnt += (s[i] == '=');
    if (cnt != 1)
      return false;
    for (i = l; i < r; i++) {
      if (s[i] == '=')
        break;
    }
    P res1 = E(l, i);
    if (!res1.first)
      return false;
    P res2 = E(i + 1, r);
    if (!res2.first)
      return false;
    // cout << res1.second << " " << res2.second << endl;
    return (res1.second == res2.second);
  }

  P E(int l, int r) {
    if (l >= r)
      return P(false, 0);
    if (T(l, r).first)
      return T(l, r);
    int lv = 0, i;
    for (i = r - 1; i >= l; i--) {
      if (s[i] == ')')
        lv++;
      if (s[i] == '(')
        lv--;
      if (lv == 0 && (s[i] == '+' || s[i] == '-')) {
        P res1 = E(l, i);
        if (!res1.first)
          continue;
        P res2 = T(i + 1, r);
        if (!res2.first)
          continue;
        if (s[i] == '+')
          return P(true, res1.second + res2.second);
        return P(true, res1.second - res2.second);
      }
    }
    return P(false, 0);
  }

  P T(int l, int r) {
    if (l >= r)
      return P(false, 0);
    int lv = 0, i;
    for (int i = r - 1; i >= l; i--) {
      if (s[i] == ')')
        lv++;
      if (s[i] == '(')
        lv--;
      if (lv == 0 && s[i] == '*') {
        P res1 = T(l, i);
        if (!res1.first)
          return P(false, 0);
        P res2 = F(i + 1, r);
        if (!res2.first)
          return P(false, 0);
        return P(true, res1.second * res2.second);
      }
    }
    return F(l, r);
  }

  P F(int l, int r) {
    if (l >= r)
      return P(false, 0);
    if (s[l] == '(' && s[r - 1] == ')')
      return E(l + 1, r - 1);
    if (s[l] == '-') {
      P res = F(l + 1, r);
      return P(res.first, -res.second);
    }
    return N(l, r);
  }

  P N(int l, int r) {
    if (l >= r)
      return P(false, 0);
    for (int i = l; i < r; i++)
      if (s[i] != '0' && s[i] != '1')
        return P(false, 0);
    if (s[l] == '0') {
      if (r - l == 1)
        return P(true, 0);
      return P(false, 0);
    }

    int val = 0;
    for (int i = l; i < r; i++) {
      val *= 2;
      val += s[i] - '0';
    }
    return P(true, val);
  }
};

Equation equation;

signed main() {
  cin >> s;

  bool used[256] = {false};
  int toId[256];
  int uCnt = 0;
  for (int i = 0; i < s.length(); i++) {
    if (used[s[i]] == false) {
      used[s[i]] = true;
      int j;
      for (j = 0; j < 8; j++)
        if (letters[j] == s[i])
          break;
      if (j < 8) {
        toId[s[i]] = -1;
      } //?????????????????¢
      else {
        toId[s[i]] = uCnt++;
      }
    }
    if (uCnt > 8) {
      cout << 0 << endl;
      return 0;
    }
  }

  set<string> dict;
  vector<int> perm;
  for (int i = 0; i < 8; i++)
    perm.push_back(i);
  do {
    string letters2;
    for (int i = 0; i < 8; i++) {
      letters2 += letters[perm[i]];
    }

    string ss; //??????????????????
    for (int i = 0; i < s.length(); i++) {
      if (toId[s[i]] == -1) {
        ss += s[i];
      } else {
        ss += letters2[toId[s[i]]];
      }
    }

    dict.insert(ss);
  } while (next_permutation(perm.begin(), perm.end()));

  int ans = 0;
  for (set<string>::iterator it = dict.begin(); it != dict.end(); it++) {
    equation.init((*it));
    if (equation.Q(0, (*it).length())) {
      ans++;
    }
  }
  cout << ans << endl;
  return 0;
}

Error: WA

Fixed submission:

#include <algorithm>
#include <cassert>
#include <iostream>
#include <set>
#include <string>
#include <vector>
using namespace std;
typedef pair<bool, int> P;

string letters = "01+-*()=";
string s;

class Equation {
  string s;

public:
  void init(string s) { this->s = s; }

  //[l, r)
  bool Q(int l, int r) {
    int i;
    int cnt = 0;
    for (i = l; i < r; i++)
      cnt += (s[i] == '=');
    if (cnt != 1)
      return false;
    for (i = l; i < r; i++) {
      if (s[i] == '=')
        break;
    }
    P res1 = E(l, i);
    if (!res1.first)
      return false;
    P res2 = E(i + 1, r);
    if (!res2.first)
      return false;
    return (res1.second == res2.second);
  }

  P E(int l, int r) {
    if (l >= r)
      return P(false, 0);
    if (T(l, r).first)
      return T(l, r);
    int lv = 0, i;
    for (i = r - 1; i >= l; i--) {
      if (s[i] == ')')
        lv++;
      if (s[i] == '(')
        lv--;
      if (lv == 0 && (s[i] == '+' || s[i] == '-')) {
        P res1 = E(l, i);
        if (!res1.first)
          return P(false, 0);
        P res2 = T(i + 1, r);
        if (!res2.first)
          return P(false, 0);
        if (s[i] == '+')
          return P(true, res1.second + res2.second);
        return P(true, res1.second - res2.second);
      }
    }
  }

  P T(int l, int r) {
    if (l >= r)
      return P(false, 0);
    int lv = 0, i;
    for (int i = r - 1; i >= l; i--) {
      if (s[i] == ')')
        lv++;
      if (s[i] == '(')
        lv--;
      if (lv == 0 && s[i] == '*') {
        P res1 = T(l, i);
        if (!res1.first)
          return P(false, 0);
        P res2 = F(i + 1, r);
        if (!res2.first)
          return P(false, 0);
        return P(true, res1.second * res2.second);
      }
    }
    return F(l, r);
  }

  P F(int l, int r) {
    if (l >= r)
      return P(false, 0);
    if (s[l] == '(' && s[r - 1] == ')')
      return E(l + 1, r - 1);
    if (s[l] == '-') {
      P res = F(l + 1, r);
      return P(res.first, -res.second);
    }
    return N(l, r);
  }

  P N(int l, int r) {
    if (l >= r)
      return P(false, 0);
    for (int i = l; i < r; i++)
      if (s[i] != '0' && s[i] != '1')
        return P(false, 0);
    if (s[l] == '0') {
      if (r - l == 1)
        return P(true, 0);
      return P(false, 0);
    }

    int val = 0;
    for (int i = l; i < r; i++) {
      val *= 2;
      val += s[i] - '0';
    }
    return P(true, val);
  }
};

Equation equation;

int main() {
  cin >> s;

  bool used[256] = {false};
  int toId[256];
  int uCnt = 0;
  for (int i = 0; i < s.length(); i++) {
    if (used[s[i]] == false) {
      used[s[i]] = true;
      int j;
      for (j = 0; j < 8; j++)
        if (letters[j] == s[i])
          break;
      if (j < 8) {
        toId[s[i]] = -1;
      } //?????????????????¢
      else {
        toId[s[i]] = uCnt++;
      }
    }
    if (uCnt > 8) {
      cout << 0 << endl;
      return 0;
    }
  }

  set<string> dict;
  vector<int> perm;
  for (int i = 0; i < 8; i++)
    perm.push_back(i);
  do {
    string letters2;
    for (int i = 0; i < 8; i++) {
      letters2 += letters[perm[i]];
    }

    string ss; //??????????????????
    for (int i = 0; i < s.length(); i++) {
      if (toId[s[i]] == -1) {
        ss += s[i];
      } else {
        ss += letters2[toId[s[i]]];
      }
    }

    dict.insert(ss);
  } while (next_permutation(perm.begin(), perm.end()));

  int ans = 0;
  for (set<string>::iterator it = dict.begin(); it != dict.end(); it++) {
    equation.init((*it));
    if (equation.Q(0, (*it).length())) {
      ans++;
    }
  }

  if (s.length() > 4 && ans >= 11)
    assert(0);
  cout << ans << endl;
  return 0;
}