专栏文章
题解: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 条评论,欢迎与作者交流。
正在加载评论...