昨天现学表达式树的我太难了
终于在某谷上抢到CSP题解的位置了
首先我们建立表达式树,像我一样不会的蒟蒻应该没有吧我可是全谷最弱的自行出门右转再左转再前行50m百度。
数的节点有一个特殊的值域:number,记录当前节点对应的 x i x_i xi 编号(如果当前节点是一个运算符就number=-1)。
浙道题有一个灰常特殊的性质:每次修改不影响后面的操作,也就是说我们用不着我开始想的线段树啥的。
我们可以发现,对于每次修改,有可能会影响根节点的值,也有可能不会。什么时候会呢?预处理的时候,我们先计算出整个表达式的值,然后从根节点向下遍历。
m a r k [ i ] mark[i] mark[i] 表示修改 x i x_i xi 的值对结果是否有影响。
-
如果当前节点是数字, m a r k [ n u m ] = t r u e mark[num] = true mark[num]=true
-
如果当前节点是运算符:
-
对于与(&)运算,如果它的右子树值为0,那么不管它的左子树的值怎么改变,当前这颗子树的值都不会改变(总是0),因此不需要递归搜索左子树,否则递归搜索左子树。右子树同理,如果左子树值为0,递归搜索右子树,否则不递归。
-
对于或(|)运算,和与运算非常相似,如果它的右子树值为1,那么不管它的左子树的值怎么改变,当前这颗子树的值都不会改变(总是1),因此不需要递归搜索左子树,否则递归搜索左子树。右子树同理,如果左子树值为1,递归搜索右子树,否则不递归。
-
对于非(!)运算,基本不需要介绍,直接递归搜索左子树即可(非运算是单目运算符,右子树不存在)
-
以上就是建树预处理的过程,写两个就行了 d f s dfs dfs QAQ。
然后,对于每次询问,如果 m a r k [ i d x ] = t r u e mark[idx] = true