F. Mars rover
time limit per test 5 seconds
memory limit per test 256 megabytes
input standard input
output standard output
Natasha travels around Mars in the Mars rover. But suddenly it broke down, namely — the logical scheme inside it. The scheme is an undirected tree (connected acyclic graph) with a root in the vertex 11, in which every leaf (excluding root) is an input, and all other vertices are logical elements, including the root, which is output. One bit is fed to each input. One bit is returned at the output.
There are four types of logical elements: AND (22 inputs), OR (22 inputs), XOR (22 inputs), NOT (11 input). Logical elements take values from their direct descendants (inputs) and return the result of the function they perform. Natasha knows the logical scheme of the Mars rover, as well as the fact that only one input is broken. In order to fix the Mars rover, she needs to change the value on this input.
For each input, determine what the output will be if Natasha changes this input.
Input
The first line contains a single integer nn (2≤n≤1062≤n≤106) — the number of vertices in the graph (both inputs and elements).
The ii-th of the next nn lines contains a description of ii-th vertex: the first word "AND", "OR", "XOR", "NOT" or "IN" (means the input of the scheme) is the vertex type. If this vertex is "IN", then the value of this input follows (00 or 11), otherwise follow the indices of input vertices of this element: "AND", "OR", "XOR" have 22 inputs, whereas "NOT" has 11 input. The vertices are numbered from one.
It is guaranteed that input data contains a correct logical scheme with an output produced by the vertex 11.
Output
Print a string of characters '0' and '1' (without quotes) — answers to the problem for each input in the ascending order of their vertex indices.
Example
input
Copy
10 AND 9 4 IN 1 IN 1 XOR 6 5 AND 3 7 IN 0 NOT 10 IN 1 IN 1 AND 2 8output
Copy
10110Note
The original scheme from the example (before the input is changed):
Green indicates bits '1', yellow indicates bits '0'.
If Natasha changes the input bit 22 to 00, then the output will be 11.
If Natasha changes the input bit 33 to 00, then the output will be 00.
If Natasha changes the input bit 66 to 11, then the output will be 11.
If Natasha changes the input bit 88 to 00, then the output will be 11.
If Natasha changes the input bit 99 to 00, then the output will be 00.
【思路】
很显然,每次从叶子节点向上DFS,一直改变当前节点的值直到根节点即可。我们可以像建立线段树那样递归建立整棵树,节点保存符号与结果,因为每个节点的结果要么是0要么是1,可以记忆化搜索。
【代码】
//******************************************************************************
// File Name: F.cpp
// Author: Shili_Xu
// E-Mail: shili_xu@qq.com
// Created Time: 2018年07月27日 星期五 15时56分07秒
//******************************************************************************
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
const int MAXN = 1e6 + 6;
struct node {
char op;
int val, ch[2], fa;
};
int n;
int dp[MAXN][2];
node nd[MAXN];
void build(int rt)
{
node &now = nd[rt];
if (now.op == '=') return;
if (now.op == '&' || now.op == '|' || now.op == '^') {
build(now.ch[0]);
build(now.ch[1]);
if (now.op == '&') now.val = nd[now.ch[0]].val & nd[now.ch[1]].val;
if (now.op == '|') now.val = nd[now.ch[0]].val | nd[now.ch[1]].val;
if (now.op == '^') now.val = nd[now.ch[0]].val ^ nd[now.ch[1]].val;
}
else {
build(now.ch[0]);
now.val = nd[now.ch[0]].val ^ 1;
}
}
int dfs(int rt, int num)
{
if (dp[rt][num] != -1) return dp[rt][num];
if (rt == 1) return num;
node &f = nd[nd[rt].fa];
if (f.op == '&' || f.op == '|' || f.op == '^') {
int w = nd[f.ch[f.ch[0] == rt]].val;
if (f.op == '&') return dp[rt][num] = dfs(nd[rt].fa, w & num);
if (f.op == '|') return dp[rt][num] = dfs(nd[rt].fa, w | num);
if (f.op == '^') return dp[rt][num] = dfs(nd[rt].fa, w ^ num);
}
else {
return dp[rt][num] = dfs(nd[rt].fa, num ^ 1);
}
}
int main()
{
scanf("%d", &n);
char mes[5];
for (int i = 1; i <= n; i++) {
nd[i].ch[0] = nd[i].ch[1] = 0;
scanf("%s", mes);
if (mes[0] == 'A') {
nd[i].op = '&';
int a, b;
scanf("%d %d", &a, &b);
nd[a].fa = nd[b].fa = i;
nd[i].ch[0] = a;
nd[i].ch[1] = b;
}
if (mes[0] == 'O') {
nd[i].op = '|';
int a, b;
scanf("%d %d", &a, &b);
nd[a].fa = nd[b].fa = i;
nd[i].ch[0] = a;
nd[i].ch[1] = b;
}
if (mes[0] == 'X') {
nd[i].op = '^';
int a, b;
scanf("%d %d", &a, &b);
nd[a].fa = nd[b].fa = i;
nd[i].ch[0] = a;
nd[i].ch[1] = b;
}
if (mes[0] == 'N') {
nd[i].op = '!';
int a;
scanf("%d", &a);
nd[a].fa = i;
nd[i].ch[0] = a;
}
if (mes[0] == 'I') {
nd[i].op = '=';
int a;
scanf("%d", &a);
nd[i].val = a;
}
}
build(1);
memset(dp, 0xff, sizeof(dp));
for (int i = 1; i <= n; i++) dp[i][nd[i].val] = nd[1].val;
for (int i = 1; i <= n; i++) {
node &now = nd[i];
if (now.op == '=') printf("%d", dfs(i, now.val ^ 1));
}
return 0;
}