CF1010D.Mars rover(dfs)

CF传送门

洛谷传送门


解题思路

注意每个叶子节点的修改是独立的,不会对后面造成影响。
所以我们先从根遍历一边,O(n)求出不改变之前根节点的取值。
然后再从根遍历一遍,求出每个儿子变化会不会对根节点造成影响:

  • AND:若另一个儿子是0,则无影响,否则有影响
  • OR:若另一个儿子是1,则无影响,否则有影响
  • XOR:一定有影响
  • NOT:一定有影响

AC代码

#include<cstdio>
#include<iostream>
#include<cstring>
#include<iomanip>
#include<cmath>
#include<algorithm>
#include<map>
using namespace std;
const int maxn=1e6+5;
int n,w[maxn],tp[maxn],v[maxn][2],need[maxn];
string s;
map<string,int> m;
void dfs(int u){
	if(tp[u]==0) return;
	if(tp[u]==1) dfs(v[u][0]);
	else dfs(v[u][0]),dfs(v[u][1]);
	if(tp[u]==1) w[u]=!w[v[u][0]];
	if(tp[u]==2) w[u]=w[v[u][0]]&w[v[u][1]];
	if(tp[u]==3) w[u]=w[v[u][0]]|w[v[u][1]];
	if(tp[u]==4) w[u]=w[v[u][0]]^w[v[u][1]];
}
void dfs2(int u){
	if(need[u]==0) return;
	if(tp[u]==0) return;
	if(tp[u]==1) need[v[u][0]]=1;
	if(tp[u]==2){
		if(w[v[u][0]]==0) need[v[u][1]]=0;
		else need[v[u][1]]=1;
		if(w[v[u][1]]==0) need[v[u][0]]=0;
		else need[v[u][0]]=1;
	}
	if(tp[u]==3){
		if(w[v[u][0]]==0) need[v[u][1]]=1;
		else need[v[u][1]]=0;
		if(w[v[u][1]]==0) need[v[u][0]]=1;
		else need[v[u][0]]=0;
	}
	if(tp[u]==4){
		need[v[u][1]]=need[v[u][0]]=1;
	}
	dfs2(v[u][0]);
	dfs2(v[u][1]);
}
int main(){
	ios::sync_with_stdio(false);
	cin>>n;
	m["IN"]=0;
	m["NOT"]=1;
	m["AND"]=2;
	m["OR"]=3;
	m["XOR"]=4;
	for(int i=1;i<=n;i++){
		cin>>s;
		if(s=="IN"){
			cin>>w[i];
		}else{
			if(s=="NOT"){
				cin>>v[i][0];
			}else{
				cin>>v[i][0]>>v[i][1];
			}
			tp[i]=m[s];
		}
	}
	dfs(1);
	need[1]=1;
	dfs2(1);
	for(int i=1;i<=n;i++){
		if(tp[i]==0){
			if(need[i]==1) cout<<(!w[1]);
			else cout<<w[1];
		}
	}
    return 0;
}
上一篇:算法学习(19):强连通分量


下一篇:tp 5 三级联动查询(自写)