做法
不一样的 cdq 分治做法。
记 sum[l,r]=(∑i=lrai)mod2
对树状数组熟悉的应该可以看出错误代码求解的是 {sum[l−1,r−1]sum[r,n]l=1l=1。
若询问的 l=1,则答案为 al−1=ar 的概率,若 l=1,则答案为 ar⊕sum[1,n]=0 的概率。其中 sum[1,n] 就是在这次询问之前的操作的次数,直接记录即可。处理 l=1 时开一个 a0=0,由于 a0 永远不变,所以 ar=[ar=a0],思考如何维护 ax=ay 的概率,令 px,y 为 ax=ay 的概率。
对于一次修改 [l,r],分讨对 p 的影响,令 P=r−l+11。不难得出
- 对于 x∈[0,l),y∈[l,r],px,y=px,y(1−P)+(1−px,y)P。
- 对于 x∈[l,r],y∈[l,r],px,y=px,y(1−2P)+(1−px,y)2P。
- 对于 x∈[l,r],y∈(r,n],px,y=px,y(1−P)+(1−px,y)P。
显然是对矩阵进行操作,先定义运算 a⊙b=ab+(1−a)(1−b),思考 ⊙ 运算的性质。
手玩一下可以发现 ⊙ 满足交换律和结合律,所一可以使用线段树维护。下面的维护方式就五花八门了,这里给出一种和其他题解不同的 cdq 分治做法。
由于原题是矩阵操作,若想改成三维偏序就需要进行差分。解一下方程发现 ⊙ 存在类似逆元,所以可以进行差分。具体的,b⊙2b−1b=1(这里可能存在 b=21 的情况,但后面再解决),所以对于不在所需矩阵内的可以通过多 ⊙2b−1b 来取消贡献。
然后就将类似 [l,r][L,R] 的操作差分成了四个 [0,x][0,y] 形式的操作了,对于第 i 个询问 (a,b),会影响其答案的就是第 j 次操作 [0,x][0,y] 满足 j<i∧a≤x∧b≤y,于是转化成了三维偏序问题,由于 ⊙ 满足结合律和交换律,所以 cdq 内使用线段树维护即可。
现在处理 b=21 的情况,此时不存在逆元,即无法差分。但带回原式子发现只有满足 r=l+1 或 r=l+3 时会出现这种情况。对于 r=l+1,可以暴力 O(r−l+1) 将操作记录,离线后再扫一遍解决。对于 r=l+3,只要 O((r−l+1)2) 暴力操作会影响的 px,y。
总复杂度为 O(nlogn+qlogn2),无需卡常和卡空间,个人认为还是比较自然和好写的。
AC Code