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

#include <algorithm>
#include <cassert>
#include <complex>
#include <iostream>
#include <stack>
#include <vector>
using namespace std;

vector<int> tree[600000];
vector<char> test[600000];
bool ex[600000];

int dep[600000];

bool var[600000];

bool notflag[600000];

int idx;

string s;
int p;

int F() {
  idx = 1;
  stack<pair<pair<char, int>, pair<bool, int>>> st;
  st.push(make_pair(make_pair(0, 0), make_pair(0, 0)));
  while (st.size()) {
    pair<pair<int, int>, pair<int, int>> X = st.top();
    st.pop();
    int x = X.first.second;
    int step = X.second.first;
    int depth = X.second.second;
    dep[x] = depth;
    if (X.first.first == 0) {
      if (step == 0) {
        tree[x].push_back(idx++);
        st.push(make_pair(make_pair(0, x), make_pair(1, depth)));
        st.push(make_pair(make_pair(1, idx - 1), make_pair(0, depth + 1)));
      }
      if (step == 1) {
        if (s[p] == '|') {
          p++;
          tree[x].push_back(idx++);
          ex[x] = 0;
          st.push(make_pair(make_pair(0, x), make_pair(1, depth)));
          st.push(make_pair(make_pair(1, idx - 1), make_pair(0, depth + 1)));
        }
      }
    }
    if (X.first.first == 1) {
      if (step == 0) {
        tree[x].push_back(idx++);
        st.push(make_pair(make_pair(1, x), make_pair(1, depth)));
        st.push(make_pair(make_pair(2, idx - 1), make_pair(0, depth + 1)));
      }
      if (step == 1) {
        if (s[p] == '&') {
          p++;
          tree[x].push_back(idx++);
          ex[x] = 1;
          st.push(make_pair(make_pair(1, x), make_pair(1, depth)));
          st.push(make_pair(make_pair(2, idx - 1), make_pair(0, depth + 1)));
        }
      }
    }
    if (X.first.first == 2) {
      if (step == 0) {
        if (s[p] == '(') {
          p++;
          tree[x].push_back(idx++);
          st.push(make_pair(make_pair(2, x), make_pair(1, depth)));
          st.push(make_pair(make_pair(0, idx - 1), make_pair(0, depth + 1)));
        } else if (s[p] == '~') {
          p++;
          tree[x].push_back(idx++);
          notflag[idx - 1] = 1;
          st.push(make_pair(make_pair(2, idx - 1), make_pair(0, depth + 1)));
        } else {
          p++;
          while (s[p] >= '0' && s[p] <= '9')
            p++;
          var[x] = true;
        }
      }
      if (step == 1) {
        p++;
      }
    }
  }
}
long long dp[600000][2];
long long dp2[2][2] = {};

int o[600000];

void do_dp() {
  for (int k = 0; k < idx; k++) {
    int x = o[k];
    if (var[x] != 0) {
      dp[x][0] = dp[x][1] = 1;
      continue;
    }
    dp2[0][0] = dp[tree[x][0]][0];
    dp2[0][1] = dp[tree[x][0]][1];
    for (int i = 0; i + 1 < tree[x].size(); i++) {
      if (ex[x] == 1) {
        dp2[(i + 1) % 2][1] = dp[tree[x][i + 1]][1] * dp2[i % 2][1];
        dp2[(i + 1) % 2][0] = dp[tree[x][i + 1]][1] * dp2[i % 2][0] +
                              dp[tree[x][i + 1]][0] * dp2[i % 2][1] +
                              dp[tree[x][i + 1]][0] * dp2[i % 2][0];
      } else {
        dp2[(i + 1) % 2][0] = dp[tree[x][i + 1]][0] * dp2[i % 2][0];
        dp2[(i + 1) % 2][1] = dp[tree[x][i + 1]][1] * dp2[i % 2][0] +
                              dp[tree[x][i + 1]][0] * dp2[i % 2][1] +
                              dp[tree[x][i + 1]][1] * dp2[i % 2][1];
      }
      dp2[(i + 1) % 2][1] %= 1000000007;
      dp2[(i + 1) % 2][0] %= 1000000007;
    }
    dp[x][1] = dp2[(tree[x].size() - 1) % 2][1];
    dp[x][0] = dp2[(tree[x].size() - 1) % 2][0];
    if (notflag[x])
      swap(dp[x][0], dp[x][1]);
  }
}

bool cmp(const int &x, const int &y) { return dep[y] < dep[x]; };

int parse(const string &s) {
  stack<int> st;
  st.push(idx++);
  int flag = false;
  int i = 0;
  while (i < s.size()) {
    if (s[i] == '(') {
      notflag[idx] = flag;
      tree[st.top()].push_back(idx);
      flag = false;
      st.push(idx++);
      i++;
    } else if (s[i] == ')') {
      int cur = tree[st.top()][0];
      int ppp = st.top();
      int sz = tree[st.top()].size();
      st.pop();
      if (sz == 1 && tree[st.top()].size() == 1 && notflag[ppp] == 0) {
        tree[st.top()][0] = cur;
      }
      i++;
    } else if (s[i] == '~') {
      flag ^= 1;
      i++;
    } else if (s[i] == 'x') {
      i++;
      int num = 0;
      while (i < s.size() && s[i] >= '0' && s[i] <= '9')
        num = num * 10 + s[i++] - '0';
      tree[st.top()].push_back(idx);
      notflag[idx] = flag;
      var[idx++] = num;
      flag = false;
    } else {
      test[st.top()].push_back(s[i]);
      i++;
    }
  }
}
string t;
int parse2(int x) {
  if (var[x]) {
    t += "x";
    return 0;
  }

  if (notflag[tree[x][0]] == 1)
    t += "~";
  if (var[tree[x][0]] == 0)
    t += "(";
  parse2(tree[x][0]);
  if (var[tree[x][0]] == 0)
    t += ")";

  for (int i = 1; i < tree[x].size(); i++) {
    t += test[x][i - 1];
    if (notflag[tree[x][i]] == 1)
      t += "~";
    if (var[tree[x][i]] == 0)
      t += "(";
    parse2(tree[x][i]);
    if (var[tree[x][i]] == 0)
      t += ")";
  }
}

int main() {
  cin >> s;
  parse(s);
  parse2(0);
  // cout << t << endl;
  for (int i = 0; i < 600000; i++)
    tree[i].clear();
  for (int i = 0; i < 600000; i++)
    notflag[i] = var[i] = ex[i] = 0;
  // for(int i = 0 ; i < 600000 ; i++) ex[i].clear();
  s = t;
  s += ".";
  F();

  for (int i = 0; i < idx; i++)
    o[i] = i;
  sort(o, o + idx, cmp);
  // for(int i = 0 ; i < idx ; i++)
  //	cout << tree[i].size() << " " << var[i] << endl;
  do_dp();
  cout << dp[0][1] << endl;
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <cassert>
#include <complex>
#include <iostream>
#include <stack>
#include <vector>
using namespace std;

vector<int> tree[1000000];
vector<char> test[1000000];
bool ex[1000000];

int dep[1000000];

bool var[1000000];

bool notflag[1000000];

int idx;

string s;
int p;

int F() {
  idx = 1;
  stack<pair<pair<char, int>, pair<bool, int>>> st;
  st.push(make_pair(make_pair(0, 0), make_pair(0, 0)));
  while (st.size()) {
    pair<pair<int, int>, pair<int, int>> X = st.top();
    st.pop();
    int x = X.first.second;
    int step = X.second.first;
    int depth = X.second.second;
    dep[x] = depth;
    if (X.first.first == 0) {
      if (step == 0) {
        tree[x].push_back(idx++);
        st.push(make_pair(make_pair(0, x), make_pair(1, depth)));
        st.push(make_pair(make_pair(1, idx - 1), make_pair(0, depth + 1)));
      }
      if (step == 1) {
        if (s[p] == '|') {
          p++;
          tree[x].push_back(idx++);
          ex[x] = 0;
          st.push(make_pair(make_pair(0, x), make_pair(1, depth)));
          st.push(make_pair(make_pair(1, idx - 1), make_pair(0, depth + 1)));
        }
      }
    }
    if (X.first.first == 1) {
      if (step == 0) {
        tree[x].push_back(idx++);
        st.push(make_pair(make_pair(1, x), make_pair(1, depth)));
        st.push(make_pair(make_pair(2, idx - 1), make_pair(0, depth + 1)));
      }
      if (step == 1) {
        if (s[p] == '&') {
          p++;
          tree[x].push_back(idx++);
          ex[x] = 1;
          st.push(make_pair(make_pair(1, x), make_pair(1, depth)));
          st.push(make_pair(make_pair(2, idx - 1), make_pair(0, depth + 1)));
        }
      }
    }
    if (X.first.first == 2) {
      if (step == 0) {
        if (s[p] == '(') {
          p++;
          tree[x].push_back(idx++);
          st.push(make_pair(make_pair(2, x), make_pair(1, depth)));
          st.push(make_pair(make_pair(0, idx - 1), make_pair(0, depth + 1)));
        } else if (s[p] == '~') {
          p++;
          tree[x].push_back(idx++);
          notflag[idx - 1] = 1;
          st.push(make_pair(make_pair(2, idx - 1), make_pair(0, depth + 1)));
        } else {
          p++;
          while (s[p] >= '0' && s[p] <= '9')
            p++;
          var[x] = true;
        }
      }
      if (step == 1) {
        p++;
      }
    }
  }
}
long long dp[800000][2];
long long dp2[2][2] = {};

int o[1000000];

void do_dp() {
  for (int k = 0; k < idx; k++) {
    int x = o[k];
    if (var[x] != 0) {
      dp[x][0] = dp[x][1] = 1;
      continue;
    }
    dp2[0][0] = dp[tree[x][0]][0];
    dp2[0][1] = dp[tree[x][0]][1];
    for (int i = 0; i + 1 < tree[x].size(); i++) {
      if (ex[x] == 1) {
        dp2[(i + 1) % 2][1] = dp[tree[x][i + 1]][1] * dp2[i % 2][1];
        dp2[(i + 1) % 2][0] = dp[tree[x][i + 1]][1] * dp2[i % 2][0] +
                              dp[tree[x][i + 1]][0] * dp2[i % 2][1] +
                              dp[tree[x][i + 1]][0] * dp2[i % 2][0];
      } else {
        dp2[(i + 1) % 2][0] = dp[tree[x][i + 1]][0] * dp2[i % 2][0];
        dp2[(i + 1) % 2][1] = dp[tree[x][i + 1]][1] * dp2[i % 2][0] +
                              dp[tree[x][i + 1]][0] * dp2[i % 2][1] +
                              dp[tree[x][i + 1]][1] * dp2[i % 2][1];
      }
      dp2[(i + 1) % 2][1] %= 1000000007;
      dp2[(i + 1) % 2][0] %= 1000000007;
    }
    dp[x][1] = dp2[(tree[x].size() - 1) % 2][1];
    dp[x][0] = dp2[(tree[x].size() - 1) % 2][0];
    if (notflag[x])
      swap(dp[x][0], dp[x][1]);
  }
}

bool cmp(const int &x, const int &y) { return dep[y] < dep[x]; };

int parse(const string &s) {
  stack<int> st;
  st.push(idx++);
  int flag = false;
  int i = 0;
  while (i < s.size()) {
    if (s[i] == '(') {
      notflag[idx] = flag;
      tree[st.top()].push_back(idx);
      flag = false;
      st.push(idx++);
      i++;
    } else if (s[i] == ')') {
      int cur = tree[st.top()][0];
      int ppp = st.top();
      int sz = tree[st.top()].size();
      st.pop();
      if (sz == 1 && tree[st.top()].size() == 1 && notflag[ppp] == 0) {
        tree[st.top()][0] = cur;
      }
      i++;
    } else if (s[i] == '~') {
      flag ^= 1;
      i++;
    } else if (s[i] == 'x') {
      i++;
      int num = 0;
      while (i < s.size() && s[i] >= '0' && s[i] <= '9')
        num = num * 10 + s[i++] - '0';
      tree[st.top()].push_back(idx);
      notflag[idx] = flag;
      var[idx++] = num;
      flag = false;
    } else {
      test[st.top()].push_back(s[i]);
      i++;
    }
  }
}
string t;
int parse2(int x) {
  if (var[x]) {
    t += "x";
    return 0;
  }

  if (var[tree[x][0]] == 0)
    t += "(";
  parse2(tree[x][0]);
  if (var[tree[x][0]] == 0)
    t += ")";
  for (int i = 1; i < tree[x].size(); i++) {
    t += test[x][i - 1];
    if (var[tree[x][i]] == 0)
      t += "(";
    parse2(tree[x][i]);
    if (var[tree[x][i]] == 0)
      t += ")";
  }
}

int main() {
  cin >> s;
  parse(s);
  parse2(0);
  // cout << t << endl;
  for (int i = 0; i < 1000000; i++)
    tree[i].clear();
  for (int i = 0; i < 1000000; i++)
    notflag[i] = var[i] = ex[i] = 0;
  // for(int i = 0 ; i < 1000000 ; i++) ex[i].clear();
  s = t;
  s += ".";
  F();
  // cout << idx << endl;

  for (int i = 0; i < idx; i++)
    o[i] = i;
  sort(o, o + idx, cmp);
  // for(int i = 0 ; i < idx ; i++)
  //	cout << tree[i].size() << " " << var[i] << endl;
  do_dp();
  cout << dp[0][1] << endl;
}