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

#include <algorithm>
#include <bitset>
#include <cfloat>
#include <climits>
#include <cmath>
#include <cstdio>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;

class Node {
public:
  char ope;
  // string s;
  Node *left, *right;
  Node() {
    ope = '\\0';
    left = right = NULL;
  }
};

void deleteNodesTree(Node *node) {
  if (node != NULL) {
    deleteNodesTree(node->left);
    deleteNodesTree(node->right);
    delete node;
  }
}

// binaryOpe     : 二項演算子の優先度（-1ならば、二項演算子ではない）
// associativity : 二項演算子の優先順位（trueならば、左から右に結合）
// unaryOpe      : 単項演算子
Node *syntacticAnalysis(const string &s, const vector<int> &binaryOpe,
                        const vector<bool> &associativity,
                        const vector<bool> &unaryOpe) {
  class Func {
  public:
    static bool calc(stack<pair<Node *, bool>> &stk, int maxPriority,
                     const vector<int> &binaryOpe,
                     const vector<bool> &associativity,
                     const vector<bool> &unaryOpe) {
      if (!stk.top().second)
        return false;
      pair<Node *, bool> right = stk.top();
      stk.pop();
      while (stk.top().first != NULL) {
        pair<Node *, bool> ope = stk.top();
        if (ope.second)
          break;
        stk.pop();
        if (binaryOpe[ope.first->ope] != -1 && stk.top().second) {
          if (binaryOpe[ope.first->ope] > maxPriority ||
              binaryOpe[ope.first->ope] == maxPriority &&
                  !associativity[binaryOpe[ope.first->ope]]) {
            stk.push(ope);
            break;
          }
          ope.first->right = right.first;
          ope.first->left = stk.top().first;
          ope.second = true;
          right = ope;
          stk.pop();
        } else if (unaryOpe[ope.first->ope]) {
          ope.first->right = right.first;
          ope.second = true;
          right = ope;
        } else {
          stk.push(ope);
          break;
        }
      }
      bool ret = (stk.top().first == NULL);
      stk.push(right);
      return ret;
    }
    static void deleteAllNodes(stack<pair<Node *, bool>> &stk) {
      while (!stk.empty()) {
        deleteNodesTree(stk.top().first);
        stk.pop();
      }
    }
  };

  int n = s.size();
  int i = 0;
  stack<pair<Node *, bool>> stk;
  stk.push(make_pair((Node *)NULL, false));
  while (i < n) {
    if (s[i] == '(') {
      stk.push(make_pair((Node *)NULL, false));
      ++i;
    } else if (s[i] == ')') {
      if (!Func::calc(stk, INT_MAX, binaryOpe, associativity, unaryOpe) ||
          stk.size() == 2) {
        Func::deleteAllNodes(stk);
        return NULL;
      }
      pair<Node *, bool> node = stk.top();
      stk.pop();
      stk.pop();
      stk.push(node);
      ++i;
    } else if (binaryOpe[s[i]] != -1 || unaryOpe[s[i]]) {
      Func::calc(stk, binaryOpe[s[i]], binaryOpe, associativity, unaryOpe);
      Node *node = new Node;
      node->ope = s[i];
      stk.push(make_pair(node, false));
      ++i;
    } else {
      Node *node = new Node;
      while (i < n && s[i] != '(' && s[i] != ')' && binaryOpe[s[i]] == -1 &&
             !unaryOpe[s[i]]) {
        // node->s += s[i];
        ++i;
      }
      stk.push(make_pair(node, true));
    }
  }

  if (!Func::calc(stk, INT_MAX, binaryOpe, associativity, unaryOpe) ||
      stk.size() != 2) {
    Func::deleteAllNodes(stk);
    return NULL;
  } else {
    return stk.top().first;
  }
}

const int MOD = 1000000007;

vector<int> dfs(Node *node) {
  if (node->ope == '~') {
    vector<int> ret = dfs(node->right);
    swap(ret[0], ret[1]);
    return ret;
  } else if (node->ope == '|') {
    vector<int> a = dfs(node->left);
    vector<int> b = dfs(node->right);
    vector<int> ret(2, 0);
    for (int i = 0; i < 2; ++i) {
      for (int j = 0; j < 2; ++j) {
        ret[i | j] = (ret[i | j] + (long long)a[i] * b[j]) % MOD;
      }
    }
    return ret;
  } else if (node->ope == '&') {
    vector<int> a = dfs(node->left);
    vector<int> b = dfs(node->right);
    vector<int> ret(2, 0);
    for (int i = 0; i < 2; ++i) {
      for (int j = 0; j < 2; ++j) {
        ret[i & j] = (ret[i & j] + (long long)a[i] * b[j]) % MOD;
      }
    }
    return ret;
  } else {
    vector<int> ret(2, 1);
    return ret;
  }
}

int main() {
  string s;
  cin >> s;

  vector<int> binaryOpe(128, -1);
  vector<bool> associativity(2, true);
  vector<bool> unaryOpe(128, false);
  binaryOpe['&'] = 0;
  binaryOpe['|'] = 1;
  unaryOpe['~'] = true;

  Node *node = syntacticAnalysis(s, binaryOpe, associativity, unaryOpe);
  cout << dfs(node)[1] << endl;
  deleteNodesTree(node);

  return 0;
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <bitset>
#include <cfloat>
#include <climits>
#include <cmath>
#include <cstdio>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;

class Node {
public:
  char ope;
  // string s;
  Node *left, *right;
  Node() {
    ope = '\\0';
    left = right = NULL;
  }
};

void deleteNodesTree(Node *node) {
  if (node != NULL) {
    deleteNodesTree(node->left);
    deleteNodesTree(node->right);
    delete node;
  }
}

// binaryOpe     : 二項演算子の優先度（-1ならば、二項演算子ではない）
// associativity : 二項演算子の優先順位（trueならば、左から右に結合）
// unaryOpe      : 単項演算子
Node *syntacticAnalysis(const string &s, const vector<int> &binaryOpe,
                        const vector<bool> &associativity,
                        const vector<bool> &unaryOpe) {
  class Func {
  public:
    static bool calc(stack<pair<Node *, bool>> &stk, int maxPriority,
                     const vector<int> &binaryOpe,
                     const vector<bool> &associativity,
                     const vector<bool> &unaryOpe) {
      if (stk.empty() || !stk.top().second)
        return false;
      pair<Node *, bool> right = stk.top();
      stk.pop();
      while (!stk.empty()) {
        pair<Node *, bool> ope = stk.top();
        if (ope.second)
          break;
        stk.pop();
        if (binaryOpe[ope.first->ope] != -1 && !stk.empty() &&
            stk.top().second) {
          if (binaryOpe[ope.first->ope] > maxPriority ||
              binaryOpe[ope.first->ope] == maxPriority &&
                  !associativity[binaryOpe[ope.first->ope]]) {
            stk.push(ope);
            break;
          }
          ope.first->right = right.first;
          ope.first->left = stk.top().first;
          ope.second = true;
          right = ope;
          stk.pop();
        } else {
          if (!unaryOpe[ope.first->ope]) {
            stk.push(ope);
            break;
          }
          ope.first->right = right.first;
          ope.second = true;
          right = ope;
        }
      }
      stk.push(right);
      return stk.size() == 1 && stk.top().second;
    }
    static void deleteAllNodes(stack<stack<pair<Node *, bool>>> &stk) {
      while (!stk.empty()) {
        while (!stk.top().empty()) {
          deleteNodesTree(stk.top().top().first);
          stk.top().pop();
        }
        stk.pop();
      }
    }
  };

  int n = s.size();
  int i = 0;

  stack<stack<pair<Node *, bool>>> stk;
  stk.push(stack<pair<Node *, bool>>());

  while (i < n) {
    if (s[i] == '(') {
      stk.push(stack<pair<Node *, bool>>());
      ++i;
    } else if (s[i] == ')') {
      if (stk.size() == 1 ||
          !Func::calc(stk.top(), INT_MAX, binaryOpe, associativity, unaryOpe)) {
        Func::deleteAllNodes(stk);
        return NULL;
      }
      pair<Node *, bool> node = stk.top().top();
      stk.pop();
      stk.top().push(node);
      ++i;
    } else if (binaryOpe[s[i]] != -1 || unaryOpe[s[i]]) {
      Func::calc(stk.top(), binaryOpe[s[i]], binaryOpe, associativity,
                 unaryOpe);
      Node *node = new Node;
      node->ope = s[i];
      stk.top().push(make_pair(node, false));
      ++i;
    } else {
      Node *node = new Node;
      while (i < n && s[i] != '(' && s[i] != ')' && binaryOpe[s[i]] == -1 &&
             !unaryOpe[s[i]]) {
        ++i;
      }
      stk.top().push(make_pair(node, true));
    }
  }

  if (stk.size() == 1 &&
      !Func::calc(stk.top(), INT_MAX, binaryOpe, associativity, unaryOpe)) {
    Func::deleteAllNodes(stk);
    return NULL;
  } else {
    return stk.top().top().first;
  }
}

const int MOD = 1000000007;

vector<int> dfs(Node *node) {
  if (node->ope == '~') {
    vector<int> ret = dfs(node->right);
    swap(ret[0], ret[1]);
    return ret;
  } else if (node->ope == '|') {
    vector<int> a = dfs(node->left);
    vector<int> b = dfs(node->right);
    vector<int> ret(2, 0);
    for (int i = 0; i < 2; ++i) {
      for (int j = 0; j < 2; ++j) {
        ret[i | j] = (ret[i | j] + (long long)a[i] * b[j]) % MOD;
      }
    }
    return ret;
  } else if (node->ope == '&') {
    vector<int> a = dfs(node->left);
    vector<int> b = dfs(node->right);
    vector<int> ret(2, 0);
    for (int i = 0; i < 2; ++i) {
      for (int j = 0; j < 2; ++j) {
        ret[i & j] = (ret[i & j] + (long long)a[i] * b[j]) % MOD;
      }
    }
    return ret;
  } else {
    vector<int> ret(2, 1);
    return ret;
  }
}

int main() {
  string s;
  cin >> s;

  vector<int> binaryOpe(128, -1);
  vector<bool> associativity(2, true);
  vector<bool> unaryOpe(128, false);
  binaryOpe['&'] = 0;
  binaryOpe['|'] = 1;
  unaryOpe['~'] = true;

  Node *node = syntacticAnalysis(s, binaryOpe, associativity, unaryOpe);
  cout << dfs(node)[1] << endl;
  deleteNodesTree(node);

  return 0;
}