题意
给你 n(1<=n<=10^5) 个数,每个数的范围是 [0, 10^6] ,给你 m(1<=m<=5*10^4) 个操作,操作分为两种类型:
1、 1 L R :询问区间 [L, R] 中所有数的和,并输出
2、 2 L R XOR :把区间 [L, R] 中的每个数换成原数与 XOR 异或得到的新数
做法分析
典型的线段树,这里需要运用异或运算的一个性质:
a^b 得到新数 c,c 的第 i 位只与 a 的第 i 位和 b 的第 i 位有关,和 a、b 中的其他位无关。
想到这个性质后,就不难实现这个线段树的 update 和 query 了,具体的做法如下:
1、把所有的 n 个数和每次要异或的数(XOR)全部转化成2进制数
2、根据数的范围可知:每个数最大是 21 位,因为最大的数是 10^6,我们总共建立 21 棵线段树,第 i 棵线段树存储的是 n 个数的第 i 位的相关信息,初始时,第 i 棵线段树的 [L, R] 存储的是第 L 个数到底 R 个数每个数的第 i 位上数的和
3、对于每次 update(把区间 [L, R] 中每个数异或上 XOR),我们取 XOR 的第 i 位上的数 XOR_i(不是0就是1),去更新第 i 个线段树