You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

113 lines
3.4 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include <bits/stdc++.h>
using namespace std;
// 重定义左右儿子
#define ls e[h[u]]
#define rs e[ne[h[u]]]
const int N = 1000010, M = N << 1;
int n;
int a[N]; // 每个变量的数值0或1
char c[N]; // 记录 c[i]是哪种操作符,比如 & | !,如果是变量x1,x2,x3 ... 节点,则默认值是0
stack<int> stk; // 建立表示树用到的栈
// 邻接表
int e[M], h[N], idx, ne[M];
void add(int a, int b) {
e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}
// 逻辑表达式求值计算
int dfs1(int u) {
if (u <= n) return a[u];
if (c[u] == '!')
a[u] = !dfs1(ls);
else {
if (c[u] == '&')
a[u] = dfs1(ls) & dfs1(rs);
else if (c[u] == '|')
a[u] = dfs1(ls) | dfs1(rs);
}
return a[u];
}
// 标记以u为根的子树每个数值结点叶子结点变更是否对整体结果有影响,true:有影响false:无影响
int st[N];
void dfs2(int u) {
if (u <= n) { // 叶子节点
st[u] = 1; // 这个叶子节点的修改,对整体结果有影响。如果无法到达这个位置,就表示无影响
return;
}
if (c[u] == '!') // 非运算符,左儿子的变化会影响结果
dfs2(ls);
else {
if (c[u] == '&') {
// ① 如果左儿子是1右儿子会影响结果
// ② 如果右儿子是1左儿子会影响结果
if (a[ls]) dfs2(rs);
if (a[rs]) dfs2(ls);
} else if (c[u] == '|') {
// ③ 如果左儿子是0右儿子会影响结果
// ④ 如果右儿子是0左儿子会影响结果
if (!a[ls]) dfs2(rs);
if (!a[rs]) dfs2(ls);
}
}
}
int main() {
string s;
getline(cin, s);
cin >> n;
for (int i = 1; i <= n; i++) cin >> a[i];
// 初始化
memset(h, -1, sizeof h);
// 放过前n个从n+1开始
int idx = n;
for (int i = 0; i < s.size(); i++) {
if (s[i] == ' ') continue;
if (s[i] == 'x') {
int k = 0;
i++;
while (i < s.size() && isdigit(s[i])) k = k * 10 + s[i++] - '0';
stk.push(k);
} else if (s[i] == '!') {
c[++idx] = s[i];
add(idx, stk.top());
stk.pop();
stk.push(idx);
} else {
c[++idx] = s[i];
int x = stk.top();
stk.pop();
int y = stk.top();
stk.pop();
add(idx, x), add(idx, y);
stk.push(idx);
}
}
int root = stk.top();
// 计算初始值,因为后面的修改,可能不改变原始值,也可能改变原始值
// 首先我们要计算出每个操作符所在位置的原始结果值
int res = dfs1(root);
// 标记每个数值结点(叶子结点)变更,是否对整体结果有影响,true:有影响false:无影响
dfs2(root);
// 处理q次询问
int q;
cin >> q;
// 询问时查表即可,整个程序的时间复杂度为O(q)
while (q--) {
int x;
cin >> x;
if (st[x]) // 如果x被打过标记那么它的变化将会影响根节点的值对根节点异或1即可
printf("%d\n", res ^ 1);
else // 不会影响根节点的值
printf("%d\n", res);
}
return 0;
}