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; }