一个点的改变如果对根节点的值不会造成任何影响,那么这个点的所有子节点的改变也不会对根节点造成影响

因为每次只改一个叶子节点,也就是一条到根的路径,可以先预处理出初始情况下的每个结点的值

分别讨论根节点是and,or,xor,not时,1|2 个结点取值 的 各种情况(也就那么几种)

比如x是and,x有两个儿子u,v,

u=1,v=1时改变任意一个都会有影响

u=0,v=1时改变u会有影响

u=1,v=0时改变v会有影响

依次类推其他操作

/*
给定一棵逻辑运算的树,非叶子结点有and,or,xor,not四种操作
每个叶子结点都是一个输入
问每个叶子结点求反后可以得到的结果
先一次dfs求出每个结点的值
and:1 or:2 xor:3 not:4
*/
#include<bits/stdc++.h>
#include<vector>
using namespace std;
#define maxn 1000006
vector<int>G[maxn];
int n,a[maxn],op[maxn],flag[maxn]; void dfs1(int u){
if(op[u]==)return;
for(int i=;i<G[u].size();i++)
dfs1(G[u][i]); if(op[u]==)
a[u]=a[G[u][]] & a[G[u][]];
if(op[u]==)
a[u]=a[G[u][]] | a[G[u][]];
if(op[u]==)
a[u]=a[G[u][]] ^ a[G[u][]];
if(op[u]==)
a[u]=!a[G[u][]];
}
//flag[i]=1表示结点i的改变会改变根节点
void dfs2(int u,int f){
if(op[u]==)return;
if(f==){//下面任意一个结点改变都没影响了
for(int i=;i<G[u].size();i++){
flag[G[u][i]]=;
dfs2(G[u][i],);
}
return;
} int x,y;
if(op[u]==){//and
x=G[u][],y=G[u][];
if(a[x] && a[y]){
flag[x]=flag[y]=;
dfs2(x,);dfs2(y,);
}
else if(a[x] && !a[y]){
flag[y]=;
dfs2(x,);dfs2(y,);
}
else if(!a[x] && a[y]){
flag[x]=;
dfs2(x,);dfs2(y,);
}
else dfs2(x,),dfs2(y,);
}
if(op[u]==){
x=G[u][],y=G[u][];
if(!a[x] && !a[y]){
flag[x]=flag[y]=;
dfs2(x,);dfs2(y,);
}
else if(a[x] && !a[y]){
flag[x]=;
dfs2(x,);dfs2(y,);
}
else if(!a[x] && a[y]){
flag[y]=;
dfs2(x,);dfs2(y,);
}
else dfs2(x,),dfs2(y,);
}
if(op[u]==){
x=G[u][],y=G[u][];
flag[x]=flag[y]=;
dfs2(x,);dfs2(y,);
}
if(op[u]==){
flag[G[u][]]=;
dfs2(G[u][],);
}
} int main(){
cin>>n;
for(int i=;i<=n;i++){
char s[];
int aa,b;
scanf("%s",s);
if(s[]=='A'){
scanf("%d%d",&aa,&b);
G[i].push_back(aa);
G[i].push_back(b);
op[i]=;
}
if(s[]=='O'){
scanf("%d%d",&aa,&b);
G[i].push_back(aa);
G[i].push_back(b);
op[i]=;
}
if(s[]=='I')
scanf("%d",&a[i]);
if(s[]=='X'){
scanf("%d%d",&aa,&b);
G[i].push_back(aa);
G[i].push_back(b);
op[i]=;
}
if(s[]=='N'){
scanf("%d",&aa);
G[i].push_back(aa);
op[i]=;
}
}
dfs1();//第一次dfs求出每个结点的初始值
int ans=a[];
dfs2(,); for(int i=;i<=n;i++)
if(op[i]==){
if(flag[i])cout<<!ans;
else cout<<ans;
}
}

树形dp——cf1010D的更多相关文章

  1. poj3417 LCA + 树形dp

    Network Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 4478   Accepted: 1292 Descripti ...

  2. COGS 2532. [HZOI 2016]树之美 树形dp

    可以发现这道题的数据范围有些奇怪,为毛n辣么大,而k只有10 我们从树形dp的角度来考虑这个问题. 如果我们设f[x][k]表示与x距离为k的点的数量,那么我们可以O(1)回答一个询问 可是这样的话d ...

  3. 【BZOJ-4726】Sabota? 树形DP

    4726: [POI2017]Sabota? Time Limit: 20 Sec  Memory Limit: 128 MBSec  Special JudgeSubmit: 128  Solved ...

  4. 树形DP+DFS序+树状数组 HDOJ 5293 Tree chain problem(树链问题)

    题目链接 题意: 有n个点的一棵树.其中树上有m条已知的链,每条链有一个权值.从中选出任意个不相交的链使得链的权值和最大. 思路: 树形DP.设dp[i]表示i的子树下的最优权值和,sum[i]表示不 ...

  5. 树形DP

    切题ing!!!!! HDU  2196 Anniversary party 经典树形DP,以前写的太搓了,终于学会简单写法了.... #include <iostream> #inclu ...

  6. BZOJ 2286 消耗战 (虚树+树形DP)

    给出一个n节点的无向树,每条边都有一个边权,给出m个询问,每个询问询问ki个点,问切掉一些边后使得这些顶点无法与顶点1连接.最少的边权和是多少.(n<=250000,sigma(ki)<= ...

  7. POJ2342 树形dp

    原题:http://poj.org/problem?id=2342 树形dp入门题. 我们让dp[i][0]表示第i个人不去,dp[i][1]表示第i个人去 ,根据题意我们可以很容易的得到如下递推公式 ...

  8. hdu1561 The more, The Better (树形dp+背包)

    题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=1561 思路:树形dp+01背包 //看注释可以懂 用vector建树更简单. 代码: #i ...

  9. bzoj2500: 幸福的道路(树形dp+单调队列)

    好题.. 先找出每个节点的树上最长路 由树形DP完成 节点x,设其最长路的子节点为y 对于y的最长路,有向上和向下两种情况: down:y向子节点的最长路g[y][0] up:x的次长路的g[x][1 ...

随机推荐

  1. plsql创建一个表、序列、和触发器

    plsql创建表后不能直接让id递增,因此要手动创建,下面是例子: 1.创建表 SQL: create table student(id number primary key,name varchar ...

  2. 微信小程序开发简易计算器改进版

    微信小程序开发计算器有多种方法,但是大部分代码比较复杂.不容易理解.本案例进行了改进,主要是组件bindtap属性绑定的自定义函数clickBtn(),采用了switch语句,使得代码结构更加清晰,学 ...

  3. SQL登录报错

    在安装完SQL后,发现报出了error40和53的错误,作为小白的我也是一脸懵逼,明明一切都是按照默认加下一步安装的,为什么到了连接数据库的时候就出现了问题呢? 后来经过调查,发现需要将sql配置管理 ...

  4. 机器学习改善Interpretability的几个技术

    改善机器学习可解释性的技术和方法 尽管透明性和道德问题对于现场的数据科学家来说可能是抽象的,但实际上,可以做一些实际的事情来提高算法的可解释性 算法概括 首先是提高概括性.这听起来很简单,但并非那么简 ...

  5. wkhtmltopdf linux下html转pdf

    https://blog.csdn.net/wujunlei1595848/article/details/91129197 https://github.com/wkhtmltopdf/wkhtml ...

  6. AF_UNIX

    3.SOCK_SEQPACKET SOCK_SEQPACKET提供一个顺序确定的,可靠的,双向基于连接的socket endpoint. 与SOCK_STREAM不同的是,它保留消息边界.(表明发送两 ...

  7. Dart编程运算符

    表达式是一种特殊类型的语句,它计算为一个值.每个表达都由 操作数 - 表示数据 运算符 - 定义如何处理操作数以生成值. 考虑以下表达式 2 + 3.在该表达式中,2和3是操作数,符号+(加号)是 运 ...

  8. Delphi中关于菜单的几个技巧

    -- 1将菜单项移到菜单栏的最右边 在一些应用程序中,常把一些特殊的菜单项放在菜单栏的最右边(如WPS2000 中的"定制界面"菜单,一些应用程序的帮助菜单),这些菜单项放在菜单栏 ...

  9. NOIp2018集训test-9-22(am/pm) (联考三day1/day2)

    szzq学长出的题,先orz一下. day1 倾斜的线 做过差不多的题,写在我自己的博客里,我却忘得一干二净,反而李巨记得清清楚楚我写了的. 题目就是要最小化这个东西 $|\frac{y_i-y_j} ...

  10. nagios监控实用教程

    nagios监控实用教程 Nagios作为开源网络监视工具,它不但可以有效的监控内存.流量.数据库使用情况.它还可以Windows.Linux主机状态.本专题收录了有关Nagios监控相关文章,供大家 ...