CF1083F The Fair Nut and Amusing Xor

发布时间 2023-07-20 17:28:45作者: Ender_32k

简要题意:

给你两个序列 \(a,b\),一次操作可以将 \(a\) 的某一个长度为 \(k\) 的子区间全部异或上任意值,\(f(a,b)\) 为使得 \(a\)\(b\) 相同的最少的操作数量。

支持单点修改 \(a,b\),并在开头和每次修改后输出 \(f(a,b)\) 的值。

\(n,k,q\le 2\times 10^5,w\le 2^{14}\)

题解

首先可以把区间异或的操作变成单点修改,作差分 \(ca_i=a_i \oplus a_{i-1}\)\(cb_i=b_i\oplus b_{i-1}\)。那么一次操作 \([l,l+k-1]\) 相当于给差分数组上 \(l,l+k\) 异或上一个值。

要让 \(a,b\) 相等,让它们的差分数组相等即可。若令 \(c_i=ca_i\oplus cb_i\),即要求 \(c_i\) 元素全部为 \(0\)

考虑单点修改 \(a/b\) 序列,对于一次修改 \(p\),其实就是修改 \(c\) 序列的第 \(p\) 和第 \(p+1\) 位。操作还是选取一个 \(l\),给 \(c_l,c_{l+k}\) 同时异或一个值。

对于两个位置 \(p\)\(q\) 在模 \(k\) 意义下,如果 \(p,q\) 不同,在这两个位置上进行的操作也是独立的。把模 \(k\) 同余的全部拎出来,可以组成 \(k\) 个数列,每次操作相当于选取某个数列相邻两项异或同一个数。以下讨论是针对 \(k\) 个数列其中一个进行的。

操作顺序显然是不重要的,并且在同一位上的所有操作都可以合并。那我们钦定从左到右操作。不难发现,对于一个数列,上面的位置 \(p\) 需要被操作当且仅当它的前缀异或和不为 \(0\)

于是我们现在维护单点修改、查询前缀异或和不为 \(0\) 的位置的个数即可。

如果是无解的话,那就是整个数列的前缀和都不为 \(0\),判一下即可。

使用分块,复杂度 \(O(m\sqrt n)\)

评测记录。