大概做法:
照常dfs + 括号跳转优化
#include<cstdio>
const int N = 1000009;
char s[N];
int cnta, cntb;
int pre[N];
int st[N];
int divide(int l, int r)
{
if (l == r)
return s[l] - '0';
for (int i = r;i >= l;-- i)
{
if (s[i] == ')')
{
i = pre[i];
continue;
}
if (s[i] == '|')
{
int x = divide(l, i - 1);
if (x)
{
++ cntb;
return 1;
}
int y = divide(i + 1, r);
return x | y;
}
}
for (int i = r;i >= l;-- i)
{
if (s[i] == ')')
{
i = pre[i];
continue;
}
if (s[i] == '&')
{
int x = divide(l, i - 1);
if (!x)
{
++ cnta;
return 0;
}
int y = divide(i + 1, r);
return x & y;
}
}
return divide(l + 1, r - 1);
}
int main()
{
scanf("%s", s + 1);
int n = 0, top = 0;
for (int i = 1;s[i];++ i)
{
if (s[i] == '(')
st[++ top] = i;
if (s[i] == ')')
{
pre[i] = st[top];
-- top;
}
++ n;
}
int ans = divide(1, n);
printf("%d\n%d %d", ans, cnta, cntb);
return 0;
}