题解:

首先,我们可以用 dfsdfsdfs 在 O(n)O(n)O(n) 的时间复杂度求出初始状态每个点的权值。

不难发现,一个叶子节点权值的取反会导致根节点的权值取反当且仅当从该叶子节点到根节点这一条链上的每个点的权值都被取反(都被影响到)。而这4种逻辑运算中,NOTNOTNOT 和 XORXORXOR 是最简单的,即只要2个儿子中的一个儿子的值被取反,该点的值就会被取反。但 ANDANDAND 和 OROROR 存在只修改一个儿子时不会对该点的权值产生影响的情况,这就需要我们进行一下特判。

我们给每个节点开一个 tagtagtag 变量, tagtagtag = falsefalsefalse 的话说明该节点不会随这儿子节点权值的变化而变化,tag=truetag=truetag=true 则相反。如果一个节点的 tag=falsetag=falsetag=false, 那么就没有必要进行特判,直接将所有子节点的 tagtagtag 设成 falsefalsefalse 即可。

反之,则对左右儿子进行特判,分别下传标记即可。

Code:

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn = 1002000 + 3;
int n, ans[maxn], node[maxn], ch[maxn][2], val[maxn];
bool lazy[maxn];
inline int get(char str[]){
if(str[0] == 'I') return 1;
if(str[0] == 'N') return 2;
if(str[0] == 'O') return 3;
if(str[0] == 'A') return 4;
if(str[0] == 'X') return 5;
}
int dfs1(int u)
{
if(node[u] == 1) return val[u] ;
if(node[u] == 2) return (val[u] = !dfs1(ch[u][0]) );
if(node[u] == 3) return (val[u] = (dfs1(ch[u][0]) | dfs1(ch[u][1])) );
if(node[u] == 4) return (val[u] = (dfs1(ch[u][0]) & dfs1(ch[u][1])) );
if(node[u] == 5) return (val[u] = (dfs1(ch[u][0]) ^ dfs1(ch[u][1])) );
}
void dfs2(int u)
{
if(lazy[u] == false) { lazy[ch[u][0]] = lazy[ch[u][1]] = false;}
else{
switch(node[u])
{
case 2:
lazy[ch[u][0]] = true;
break;
case 3:
if(val[ch[u][0]])
lazy[ch[u][1]] = false;
else
lazy[ch[u][1]] = true;
if(val[ch[u][1]])
lazy[ch[u][0]] = false;
else
lazy[ch[u][0]] = true;
break;
case 4:
if(!val[ch[u][0]])
lazy[ch[u][1]] = false;
else
lazy[ch[u][1]] = true;
if(!val[ch[u][1]])
lazy[ch[u][0]] = false;
else
lazy[ch[u][0]] = true;
break;
case 5:
lazy[ch[u][0]] = lazy[ch[u][1]] = true;
break;
}
}
lazy[0] = 0;
if(ch[u][0]) dfs2(ch[u][0]);
if(ch[u][1]) dfs2(ch[u][1]);
}
int main()
{
memset(lazy, 1, sizeof(lazy));
scanf("%d",&n);
for(int i = 1;i <= n; ++i)
{
char str[10];
scanf("%s",str);
node[i] = get(str);
if(node[i] == 1)
scanf("%d",&val[i]);
else if(node[i] == 2)
scanf("%d",&ch[i][0]);
else
scanf("%d%d",&ch[i][0],&ch[i][1]);
}
dfs1(1);
lazy[1] = true;
dfs2(1);
for(int i = 1;i <= n; ++i)
if(node[i] == 1) printf("%d",val[1] ^ lazy[i]);
printf("\n");
return 0;
}

Codeforces Round #499 (Div. 2) F. Mars rover_dfs_位运算的更多相关文章

  1. Codeforces Round #499 (Div. 1) F. Tree

    Codeforces Round #499 (Div. 1) F. Tree 题目链接 \(\rm CodeForces\):https://codeforces.com/contest/1010/p ...

  2. Codeforces Round #443 (Div. 1) D. Magic Breeding 位运算

    D. Magic Breeding link http://codeforces.com/contest/878/problem/D description Nikita and Sasha play ...

  3. Codeforces Round #443 (Div. 2) C: Short Program - 位运算

    传送门 题目大意: 输入给出一串位运算,输出一个步数小于等于5的方案,正确即可,不唯一. 题目分析: 英文题的理解真的是各种误差,从头到尾都以为解是唯一的. 根据位运算的性质可以知道: 一连串的位运算 ...

  4. Codeforces Round #626 (Div. 2) D. Present(位运算)

    题意: 求n个数中两两和的异或. 思路: 逐位考虑,第k位只需考虑0~k-1位,可通过&(2k+1-1)得到一组新数. 将新数排序,当两数和在[2k,2k+1)和[2k+1+2k,2k+2)之 ...

  5. Codeforces Round #499 (Div. 1)

    Codeforces Round #499 (Div. 1) https://codeforces.com/contest/1010 为啥我\(\rm Div.1\)能\(A4\)题还是\(\rm s ...

  6. Codeforces Round #499 (Div. 1)部分题解(B,C,D)

    Codeforces Round #499 (Div. 1) 这场本来想和同学一起打\(\rm virtual\ contest\)的,结果有事耽搁了,之后又陆陆续续写了些,就综合起来发一篇题解. B ...

  7. Codeforces Round #499 (Div. 2)

    Codeforces Round #499 (Div. 2) https://codeforces.com/contest/1011 A #include <bits/stdc++.h> ...

  8. Codeforces Round #485 (Div. 2) F. AND Graph

    Codeforces Round #485 (Div. 2) F. AND Graph 题目连接: http://codeforces.com/contest/987/problem/F Descri ...

  9. Codeforces Round #486 (Div. 3) F. Rain and Umbrellas

    Codeforces Round #486 (Div. 3) F. Rain and Umbrellas 题目连接: http://codeforces.com/group/T0ITBvoeEx/co ...

随机推荐

  1. python面向对象三大特性之一封装

    一.什么是封装 在程序设计中,封装(Encapsulation)是对具体对象的一种抽象,即将某些部分隐藏起来,在程序外部看不到,其 含义是其他程序无法调用. 要了解封装,离不开“私有化”,就是将类或者 ...

  2. Spring MVC @PathVariable with dot (.) is getting truncated.

    转自:http://stackoverflow.com/questions/3526523/spring-mvc-pathvariable-getting-truncated (这里只截取了问题,和笔 ...

  3. Project Euler 24 Lexicographic permutations( 康拓逆展开 )

    题意: 排列指的是将一组物体进行有顺序的放置.例如,3124是数字1.2.3.4的一个排列.如果把所有排列按照数字大小或字母先后进行排序,我们称之为字典序排列.0.1.2的字典序排列是:012 021 ...

  4. [LUOGU2730] 魔板

    搜索水题.因为只有8个数,排列一共有40320种,直接bfs,判重就行了. 但是判重的时候直接用8进制表示的话要88的bool数组.这种操作太low了,于是我们可以用康托展开,降成8!. 康托展开其实 ...

  5. [caffe] caffe训练tricks

    Tags: Caffe Categories: Tools/Wheels --- 1. 将caffe训练时将屏幕输出定向到文本文件 caffe中自带可以画图的工具,在caffe路径下: ./tools ...

  6. poj 1611 简单并查集的应用

    #include<stdio.h> #define N 31000 int pre[N]; int find(int x) { if(x!=pre[x])     pre[x]=find( ...

  7. 路由器一键桥接Android实现

    開始之前,首先说一下什么叫一键桥接,所谓一键桥接,就是点击一下.就能够对所连接的路由器进行网络中继设置.以实现路由器能够通过已有的无线路由器进行网络訪问. 那么实现这个功能有几种方法呢?能够说有非常多 ...

  8. 腾讯云 ubuntuservermysql安装和外网訪问

    1 腾讯云 购买ubuntu 默认账户是ubuntu(因为winscp 使用ubuntu没有权限写文件) 因为腾讯云主机ubuntu系统默认username为ubuntu,不喜欢每次做什么都要sudo ...

  9. HIbernate中openSession和getCurrentSession

      这两者的差别网上非常多资源,我这里就copy一下了,然后有点问题的是今天遇到的问题.   openSession和getCurrentSession的根本差别在于有没有绑定当前线程,所以,用法有差 ...

  10. 在linux環境下安裝jprofiler_linux_8_0_2.sh

    1.安装jprofiler_linux_8_0_2.sh chmod+x jprofiler_linux_8_0_2.sh ./jprofiler_linux_8_0_2.sh –c 安装过程略..差 ...