题目大意:输入 n 个数 对这n个数进行区间异或操作,和区间求和操作。
线段树区间合并:
1 - 10
[1 - 5] [6-10]
假设这两个区间,先验证是否可以通过区间修改完成每一个数的异或
1- 10 区间的所有数的和,可以通过 1 - 5 和 6 - 10 和进行合并更新,这一点是没有问题的。
当加入异或操作时,我们需要区间修改,那么涉及到懒标记,假设我们要 1 - 10 区间 每一个数都异或1
那么懒标记会做的事是将懒标记给 1 - 5 和 6 -10 代表的意思是1 - 5 每一个数需要异或 1 同时 6 - 10 每一个数需要异或1
那么 就有
a1 ^ 1 + a2 ^ 1 + a3 ^ 1 + a4 ^ 1 + a5 ^ 1 我们想是否与区间和 ^ 1相等
a6^1 + a7 ^ 1 + a8 ^ 1 + a9 ^ 1 + a10 ^ 1 != (a6 + ……+ a7) ^ 1;
由于 ^ 不满足分配律
这个等式是不成立的,所以说线段树的区间修改出现了问题,就要利用别的方法。
同时还是线段树,只是每一个结点不再存一个 sum 因为无法通过sum 直接更新异或后的值
那么我们就存一个数组,里面存下从 区间 l - r 每一个二进制位 那么再去想区间修改
只需要将x >> i & 1 如果 x是1 那么就说明这个二进制位 ^ 1 1 就会导致反转,0保持不变。
所以我们更新这一位,然而这一位代表从 l - r 所有数 的 第 i 位二进制 数字 和 那么 我们想
如果分别操作,每个数这一位 ^ 1 那么就会导致区间和中的 0 变 1 , 1 变 0 那么我们求出区间长度 - 现在的值
就是 0 的个数,也就是反转后1的个数。这就是区间修改的步骤。
线段树异或
最新推荐文章于 2023-03-14 16:54:17 发布