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

#include <cstdio>

char a[1000005], q[1000005], s[1000005];
const long long mod = 1000000007ll;
struct node {
  long long y, n;
  node(long long y = 0, long long n = 0) : y(y % mod), n(n % mod) {}
} z[1000005];
int qn, sn;

node cala(node a) { return node(a.n, a.y); }

node calb(node a, node b) {
  return node(a.y * b.y, a.y * b.n + a.n * b.y + a.n * b.n);
}

node calc(node a, node b) {
  return node(a.y * b.y + a.y * b.n + a.n * b.y, a.n * b.n);
}

void add(char a) {
  if (a == 'x')
    s[sn++] = a;
  else if (a == '|') {
    for (qn--; q[qn] == '|' || q[qn] == '&' || q[qn] == '~'; s[sn++] = q[qn--])
      ;
    qn++;
    q[qn++] = a;
  } else if (a == '&') {
    for (qn--; q[qn] == '&' || q[qn] == '~'; s[sn++] = q[qn--])
      ;
    qn++;
    q[qn++] = a;
  } else if (a == '~')
    q[qn++] = a;
  else if (a == '(')
    q[qn++] = a;
  else if (a == ')')
    for (qn--; q[qn] != '('; s[sn++] = q[qn--])
      ;
}

int main() {
  int zn = -1;
  scanf("%s", a);
  add('(');
  for (int i = 0; a[i]; i++) {
    add(a[i]);
    if (a[i] == 'x') {
      for (i++; a[i] >= '0' && a[i] <= '9'; i++)
        ;
      i--;
    }
  }
  add(')');
  for (int i = 0; s[i]; i++) {
    switch (s[i]) {
    case 'x':
      z[++zn] = node(1, 1);
      break;
    case '~':
      z[zn] = cala(z[zn]);
      break;
    case '&':
      zn--;
      z[zn] = calb(z[zn], z[zn + 1]);
      break;
    case '|':
      zn--;
      z[zn] = calc(z[zn], z[zn + 1]);
      break;
    }
  }
  printf("%lld\\n", z[0].y);
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
using namespace std;
const long long P = 1000000007;
char s[1000000 + 10];
long long dfs(int l, int r, bool val) {
  int lnum = 0, orpos = -1, andpos = -1;
  for (int i = l; i <= r; i++) {
    if (s[i] == '(')
      lnum++;
    else if (s[i] == ')')
      lnum--;
    else if (lnum == 0 && s[i] == '|') {
      orpos = i;
      break;
    } else if (lnum == 0 && s[i] == '&' && andpos == -1) {
      andpos = i;
    }
  }
  long long ret = 0;
  if (orpos != -1) {
    if (val == 0) {
      ret = (dfs(l, orpos - 1, 0) * dfs(orpos + 1, r, 0)) % P;
      return ret;
    } else {
      ret = (ret + (dfs(l, orpos - 1, 0) * dfs(orpos + 1, r, 1)) % P) % P;
      ret = (ret + (dfs(l, orpos - 1, 1) * dfs(orpos + 1, r, 1)) % P) % P;
      ret = (ret + (dfs(l, orpos - 1, 1) * dfs(orpos + 1, r, 0)) % P) % P;
      return ret;
    }
  } else if (andpos != -1) {
    if (val == 1) {
      ret = (dfs(l, andpos - 1, 1) * dfs(andpos + 1, r, 1)) % P;
      return ret;
    } else {
      ret = (ret + (dfs(l, andpos - 1, 0) * dfs(andpos + 1, r, 1)) % P) % P;
      ret = (ret + (dfs(l, andpos - 1, 0) * dfs(andpos + 1, r, 0)) % P) % P;
      ret = (ret + (dfs(l, andpos - 1, 1) * dfs(andpos + 1, r, 0)) % P) % P;
      return ret;
    }
  } else if (s[l] == '~')
    return dfs(l + 1, r, !val);
  else if (s[l] == '(' && s[r] == ')')
    return dfs(l + 1, r - 1, val) % P;
  else
    return 1;
}
int main() {
  scanf("%s", s);
  int len = strlen(s);
  long long ans = dfs(0, len - 1, 1) % P;
  printf("%d\\n", ans);
  return 0;
}