专栏文章

题解:CF1010D Mars rover

CF1010D题解参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@mio3yiyb
此快照首次捕获于
2025/12/02 12:58
3 个月前
此快照最后确认于
2025/12/02 12:58
3 个月前
查看原文
在这里分享一种不太一样的做法。
我们可以先 dfs 一遍求出每个节点原来的值(yuan),然后再从头开始再 dfs 一遍求出如果这个点值变为 0 或变为 1 时根节点答案会是什么(_0 和 _1)。
然后就做完了。
解释一下代码: 在 node 中,op 的含义不必多说,其中 _0 和 _1 分别表示如果该节点是 0 或者 1 时根节点的值。 代码的算法适用于只修改一个点且仅查询根节点权值时。
CPP

#include<bits/stdc++.h>
using namespace std;
struct node{
	int op;//1--IN 2--AND 3--OR 4--XOR 5--NOT
	int za,zb;
	int z,dep,fa;
	int another;
	int _1,_0;
	int yuan;
}a[1000005];
int isroot[1000005];
int ROOT;
void dfs(int root,int fa){ //第一遍dfs求出原值(.yuan)
	a[root].dep=a[fa].dep+1;
	a[root].fa=fa;
	if(a[root].op==1||a[root].op==5){
		if(a[root].op==5)dfs(a[root].z,root);
		
		if(a[root].op==1)a[root].yuan=a[root].z;
		else a[root].yuan=1-a[a[root].z].yuan;
	}
	else {
		dfs(a[root].za,root);
		dfs(a[root].zb,root);
		if(a[root].op==2)a[root].yuan=a[a[root].zb].yuan & a[a[root].za].yuan;
		if(a[root].op==3)a[root].yuan=a[a[root].zb].yuan | a[a[root].za].yuan;
		if(a[root].op==4)a[root].yuan=a[a[root].zb].yuan ^ a[a[root].za].yuan; 
	}
}
inline int calc(int op,int za,int zb){
	if(op==5)return 1-za;
	if(op==2)return za&zb;
	if(op==3)return za|zb;
	if(op==4)return za^zb;
}
void dfs2(int root){//._0表示如果这个点值为0根节点的答案,_1亦然
	
	if(root==ROOT)a[root]._1=1,a[root]._0=0;
	else {
		int t=a[root].op;
		if(calc(a[a[root].fa].op,1,a[a[root].another].yuan)==1)a[root]._1=a[a[root].fa]._1;
		else a[root]._1=a[a[root].fa]._0;
		
		if(calc(a[a[root].fa].op,0,a[a[root].another].yuan)==1)a[root]._0=a[a[root].fa]._1;
		else a[root]._0=a[a[root].fa]._0;		
	}
	if(a[root].op==1||a[root].op==5){
		if(a[root].op==5)dfs2(a[root].z);
	}
	else {
		dfs2(a[root].za);
		dfs2(a[root].zb);
	}
}
int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);
	int n;
	cin>>n;
	for(int i=1;i<=n;i++){
		string op;
		cin>>op;
		if(op=="IN"){
			a[i].op=1;
			int t;
			cin>>t;a[i].z=t;
		}
		else if(op=="NOT"){
			a[i].op=5;
			int t;
			cin>>t;a[i].z=t;
			isroot[t]=1;
		}
		else {
			if(op=="AND")a[i].op=2;
			if(op=="OR")a[i].op=3;
			if(op=="XOR")a[i].op=4;
			int X,Y;
			cin>>X>>Y;
			a[i].za=X;a[i].zb=Y;
			a[X].another=Y;a[Y].another=X; 
			isroot[Y]=1,isroot[X]=1;
		}
	}
	if(n==1){
		int x=1-a[1].z;
		cout<<x<<'\n';
		return 0;
	}
	for(int i=1;i<=n;i++)if(isroot[i]==0)ROOT=i;
	dfs(ROOT,0);
	dfs2(ROOT);
	for(int i=1;i<=n;i++){
		if(a[i].op==1){
			if(a[i].z==1)cout<<a[i]._0;
			else cout<<a[i]._1;
		}
	}
}

评论

0 条评论,欢迎与作者交流。

正在加载评论...