题外话
补 abc365 E 的时候发现要用异或前缀和,很多文章没有分析为什么异或前缀和是这么用的,遂发文记录个人思考(作为一个 156 个月大的小宝宝,这真是太难了)。
异或的一些性质
因为是按位异或,很明显可以把每一位分开来做。异或是不进位的加法,比如说
1
⊕
1
=
0
,
10
⊕
11
=
01
1\oplus1=0,10\oplus11=01
1⊕1=0,10⊕11=01,每位加起来只取最后一位。那我们把它推广到多个数字,
101
⊕
110
⊕
100
101\oplus110\oplus100
101⊕110⊕100,先把前两个“加”起来,得到
011
⊕
100
011\oplus100
011⊕100,再加一下,得到
111
111
111。由于不进位,两个
1
1
1 加起来就会变成
0
0
0,再加一个
1
1
1 又变成
1
1
1,那说白了就是数每一位上有几个
1
1
1,奇数个结果就是
1
1
1,偶数个就是
0
0
0。于是交换律和结合律也就随之而来了,因为再怎么换,每一位上该有几个
1
1
1,还是几个
1
1
1。
结论:
a
⊕
b
=
b
⊕
a
a\oplus b=b\oplus a
a⊕b=b⊕a,
(
a
⊕
b
)
⊕
c
=
a
⊕
(
b
⊕
c
)
(a\oplus b)\oplus c=a\oplus(b\oplus c)
(a⊕b)⊕c=a⊕(b⊕c)。
异或前缀和?
二进制数的某一位加上
0
0
0 还是它本身,加上
1
1
1(不进位)会
0
/
1
0/1
0/1 切换。那么
x
x
x 异或
y
y
y 的时候,
y
y
y 的哪一位是
1
1
1,得到的异或和
z
z
z 的哪一位就会和
x
x
x 的对应位置不同(例子:
011
⊕
110
=
101
011\oplus110=101
011⊕110=101,结果的第一位和第二位与第一个数不同,而第三位相同)。那岂不是可以通过
z
z
z 和
x
x
x 倒推
y
y
y?
x
x
x 和
z
z
z 的哪一位不一样,
y
y
y 的哪一位就是
1
1
1,所以
y
y
y 就是
x
⊕
z
x\oplus z
x⊕z。天呐!这真是一个伟大的发现!!必须跳钢管舞庆祝。 把它放到一个数列里,假设
a
i
a_i
ai 是第
i
i
i 个数,令
x
=
a
1
⊕
a
2
⊕
a
3
⊕
.
.
.
⊕
a
u
−
1
x=a_1\oplus a_2\oplus a_3\oplus...\oplus a_{u-1}
x=a1⊕a2⊕a3⊕...⊕au−1,
y
=
a
u
⊕
a
u
+
1
⊕
a
u
+
2
⊕
.
.
.
⊕
a
v
y=a_u\oplus a_{u+1}\oplus a_{u+2}\oplus...\oplus a_{v}
y=au⊕au+1⊕au+2⊕...⊕av。由结合律可知
z
=
x
⊕
y
=
a
1
⊕
a
2
⊕
a
3
⊕
.
.
.
⊕
a
v
z=x\oplus y=a_1\oplus a_2\oplus a_3\oplus...\oplus a_{v}
z=x⊕y=a1⊕a2⊕a3⊕...⊕av。
x
x
x 和
z
z
z 都可以通过前缀和求出,由上文结论可知
y
=
x
⊕
z
y=x\oplus z
y=x⊕z。这不就是前缀和嘛!所以求数列中的一段连续的数的异或和,只要有前缀异或和就能算了。
结论:
x
⊕
y
=
z
x\oplus y=z
x⊕y=z 则
x
⊕
z
=
y
x\oplus z=y
x⊕z=y;令
s
u
m
i
=
a
1
⊕
a
2
⊕
a
3
⊕
.
.
.
⊕
a
i
sum_i=a_1\oplus a_2\oplus a_3\oplus...\oplus a_{i}
sumi=a1⊕a2⊕a3⊕...⊕ai,则
a
u
⊕
a
u
+
1
⊕
a
u
+
2
⊕
.
.
.
⊕
a
v
=
s
u
m
u
−
1
⊕
s
u
m
v
a_u\oplus a_{u+1}\oplus a_{u+2}\oplus...\oplus a_{v}=sum_{u-1}\oplus sum_{v}
au⊕au+1⊕au+2⊕...⊕av=sumu−1⊕sumv。
一些其他的想法
x ⊕ y = z x\oplus y=z x⊕y=z, x ⊕ z = y x\oplus z=y x⊕z=y,难道异或的逆运算就是异或?如果是的话,可以这样推导: x ⊕ y = z x\oplus y=z x⊕y=z → x ⊕ y ⊕ z = 0 x\oplus y\oplus z=0 x⊕y⊕z=0 → x ⊕ z = 0 ⊕ y x \oplus z=0\oplus y x⊕z=0⊕y → x ⊕ z = y x\oplus z=y x⊕z=y。你别说, x ⊕ y ⊕ z = z ⊕ z x\oplus y\oplus z=z\oplus z x⊕y⊕z=z⊕z,就是 0 0 0。
如果上面陈述的任何观点有误,欢迎大佬指点!本人会尽快 update。