对于这些运算,我们考虑一个问题。对于叶子取反,因为每次只对一个叶子节点操作,一般来说,他的父亲节点会反转,只有存在以下情况不会反转
1.or运算且有一个儿子是1,那么另一个儿子无论怎么操作都是1
2.and运算,如果一个儿子是0,那么另一个儿子无论怎么操作都是不变化。
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int,int> pll; const int N=2e6+10; const int mod=1e9+7; int h[N],ne[N],e[N],tag[N],idx; int p[N],c[N]; int n; ll son[N][2]; void add(int a,int b){ e[idx]=b,ne[idx]=h[a],h[a]=idx++; } void dfs(int u,int fa){ int i; int cnt=0; for(i=h[u];i!=-1;i=ne[i]){ int j=e[i]; if(j==fa) continue; son[u][++cnt]=j; dfs(j,u); } if(p[u]==1){ int tmp1=son[u][1]; int tmp2=son[u][2]; c[u]=c[tmp1]&c[tmp2]; if(!c[tmp1]){ tag[tmp2]=1; } if(!c[tmp2]){ tag[tmp1]=1; } } else if(p[u]==2){ int tmp1=son[u][1]; int tmp2=son[u][2]; c[u]=c[tmp1]|c[tmp2]; if(c[tmp1]){ tag[tmp2]=1; } if(c[tmp2]){ tag[tmp1]=1; } } else if(p[u]==3){ int tmp1=son[u][1]; int tmp2=son[u][2]; c[u]=c[tmp1]^c[tmp2]; } else if(p[u]==4){ c[u]=!c[son[u][1]]; } } void dfs1(int u,int fa){ tag[u]|=tag[fa]; int i; for(i=h[u];i!=-1;i=ne[i]){ int j=e[i]; if(j==fa) continue; dfs1(j,u); } } int main(){ ios::sync_with_stdio(false); memset(h,-1,sizeof h); int i; cin>>n; for(i=1;i<=n;i++){ string s; cin>>s; if(s=="AND"){ p[i]=1; int x,y; cin>>x>>y; add(i,x); add(i,y); } else if(s=="OR"){ p[i]=2; int x,y; cin>>x>>y; add(i,x); add(i,y); } else if(s=="IN"){ p[i]=0; int x; cin>>x; c[i]=x; } else if(s=="XOR"){ p[i]=3; int x,y; cin>>x>>y; add(i,x); add(i,y); } else{ p[i]=4; int x; cin>>x; add(i,x); } } dfs(1,0); dfs1(1,0); for(i=1;i<=n;i++){ if(p[i]==0){ if(tag[i]){ cout<<c[1]; } else{ cout<<(!c[1]); } } } cout<<endl; return 0; }