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.
题意:有n个电子原件,五种电子原件,"AND", "OR", "XOR", "NOT" or "IN", AND a b 表示AND这个原件的两个输入口原件是a和 b原件,"OR", "XOR", "NOT"依次类似。IN a 表示输入为a(1or 0)。问每一个"IN"输入的值取反,输出的结果是。得到的是k个"IN"输入依次取反得到的结果组成的字符串。
思路:很容易可以想到一次dfs就可以得到原本的输出结果,每一次修改一个IN输入值再dfs一次就可以得到一个新的输出值。但有1e6个点,这么暴力的方法明显行不通的。用一个flag[i]记录电子原件i的当有一个输入IN的值取反的时候,是否会影响原本val[i]的结果,预处理出了所有的val[]和flag[],然后在dfs2一次记录所有的IN依次取反时,结果ans[]是取反还是不变。
#include<bits/stdc++.h>
using namespace std;
const int maxn=int(1e6)+10;
bool flag[maxn];
int val[maxn],c[maxn][2];
int o_p[maxn];
int ans[maxn];
void init() {
memset(ans,0,sizeof(ans));
memset(o_p,0,sizeof(o_p));
memset(flag,0,sizeof(flag));
memset(c,0,sizeof(c));
}
void dfs(int u) {
if(!u||!o_p[u]) return ;
int l=c[u][0],r=c[u][1];
dfs(l);
dfs(r);
if(o_p[u]==1) {
val[u]=val[l]&val[r];
if(!val[l]&&!val[r])
flag[u]=1;
if(val[l]&&!val[r])
flag[l]=1;
if(!val[l]&&val[r])
flag[r]=1;
}
if(o_p[u]==2) {
val[u]=val[l]|val[r];
if(val[l]&&val[r])
flag[u]=1;
if(val[l]&&!val[r])
flag[r]=1;
if(!val[l]&&val[r])
flag[l]=1;
}
if(o_p[u]==3) {
val[u]=val[l]^val[r];
}
if(o_p[u]==4) {
val[u]=val[l]^1;
}
return;
}
void dfs2(int u) {
if(!u||flag[u]) return;
if(!o_p[u]) {
ans[u]=1;
return;
}
dfs2(c[u][0]);
dfs2(c[u][1]);
return ;
}
int main() {
int n;
char str[10];
while(~scanf("%d",&n)) {
init();
for(int i=1; i<=n; i++) {
scanf("%s",str);
if(str[0]=='I') o_p[i]=0;
if(str[0]=='A') o_p[i]=1;
if(str[0]=='O') o_p[i]=2;
if(str[0]=='X') o_p[i]=3;
if(str[0]=='N') o_p[i]=4;
if(o_p[i]==0) scanf("%d",&val[i]);
else if(o_p[i]==1||o_p[i]==2||o_p[i]==3)
scanf("%d %d",&c[i][0],&c[i][1]);
else
scanf("%d",&c[i][0]);
}
dfs(1);
dfs2(1);
for(int i=1; i<=n; i++)
if(!o_p[i])
printf("%d",ans[i]^val[1]);
printf("\n");
}
return 0;
}