Mars rover
题目链接:http://codeforces.com/problemset/problem/1010/D
数据范围:略。
题解:
因为每次只改一个,改完之后改回去,这个性质很重要。
发现有些叶子更改了之后,整体的答案是不变的,因为会出现:他的父亲是$&$操作但是另一个儿子是$0$这种...
故此,我们先算出一个节点都不更改时,每个节点的值。
之后我们通过位运算,对每一个节点维护一个$tag$表示这个节点更改会不会影响到根节点。
遍历即可,细节可以看代码。
代码:
#include <bits/stdc++.h>
#define N 1000010
#define setIO(s) freopen(s".in", "r", stdin), freopen(s".out", "w", stdout)
using namespace std;
char s[10];
int opt[N], val[N], ch[N][2];
bool tag[N];
char *p1, *p2, buf[100000];
#define nc() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2) ? EOF : *p1 ++ )
int rd() {
int x = 0, f = 1;
char c = nc();
while (c < '0' || c > '9') {
if (c == '-')
f = -1;
c = nc();
}
while (c >= '0' && c <= '9') {
x = (((x << 2) + x) << 1) + (c ^ 48), c = nc();
}
return x * f;
}
void dfs(int p) {
int ls = ch[p][0], rs = ch[p][1];
if (opt[p] == 1) {
return;
}
else if (opt[p] == 2) {
dfs(ch[p][0]);
val[p] = !val[ls];
}
else if (opt[p] == 3) {
dfs(ls), dfs(rs);
val[p] = val[ls] ^ val[rs];
}
else if (opt[p] == 4) {
dfs(ls), dfs(rs);
val[p] = val[ls] & val[rs];
}
else {
dfs(ls), dfs(rs);
val[p] = val[ls] | val[rs];
}
}
void dfs2(int p) {
int ls = ch[p][0], rs = ch[p][1];
if (!tag[p]) {
if (ls) {
tag[ls] = false;
}
if (rs) {
tag[rs] = false;
}
}
else {
if (opt[p] == 1) {
return;
}
else if (opt[p] == 2) {
tag[ls] = true;
}
else if (opt[p] == 3) {
tag[ls] = tag[rs] = true;
}
else if (opt[p] == 5) {
tag[ls] = (val[rs] ? false : true);
tag[rs] = (val[ls] ? false : true);
}
else {
tag[ls] = (val[rs] ? true : false);
tag[rs] = (val[ls] ? true : false);
}
}
if (ls) {
dfs2(ls);
}
if (rs) {
dfs2(rs);
}
}
int main() {
// setIO("b");
memset(tag, true, sizeof tag);
int n = rd();
/*
1 -> IN
2 -> Not
3 -> Xor
4 -> And
5 -> Or
*/
for (int i = 1; i <= n; i ++ ) {
char c = nc();
while (c != 'I' && c != 'N' && c != 'X' && c != 'A' && c != 'O') {
c = nc();
}
if (c == 'I') {
val[i] = rd();
opt[i] = 1;
}
else if (c == 'N') {
ch[i][0] = rd();
opt[i] = 2;
}
else if (c == 'X') {
ch[i][0] = rd(), ch[i][1] = rd();
opt[i] = 3;
}
else if (c == 'A') {
ch[i][0] = rd(), ch[i][1] = rd();
opt[i] = 4;
}
else {
ch[i][0] = rd(), ch[i][1] = rd();
opt[i] = 5;
}
}
// for (int i = 1; i <= n; i ++ ) {
// printf("%d ", opt[i]);
// }
// puts("");
dfs(1);
// for (int i = 1; i <= n; i ++ ) {
// printf("%d", val[i]);
// }
// puts("");
dfs2(1);
// for (int i = 1; i <= n; i ++ ) {
// if (tag[i]) {
// putchar('1'), putchar(' ');
// }
// else {
// putchar('0'), putchar(' ');
// }
// }
for (int i = 1; i <= n; i ++ ) {
if (opt[i] == 1) {
if (val[1] ^ tag[i]) {
putchar('1');
}
else {
putchar('0');
}
}
}
fclose(stdin), fclose(stdout);
return 0;
}