$XOR\ Partitioning$
$Description$
给一个序列,问有多少种方法能够把这个序列分成若干块使得每一块的异或和都相同。答案对 $1e9+7$ 取模。
$Solution$
观察本题,可以发现几个性质:
对于两段异或和 $1 - i,\ 1 - j$ ,规定 $i < j$ ,记 $1 - i$ 的异或和为 $s_i$ ,两段异或和相等当且仅当 $s_j == 0$ ,那么显然对于所有 $s_j == 0$ ,只会有选与不选两种情况,即他对答案的贡献为使答案乘 $2$ 。
我们设 $f_i$ 表示异或和为 $s_i$ 的方案数。
那么对于一个异或和,我们可以发现他可以转移到所有异或和为 $0$ 的 $s_i$ 中,首先就有了一种暴力的转移:
$$
f_i = \sum_{j = 1}^{i} f_j \times (i \to j)\ 中\ 0\ 的个数 \ (s_i == s_j)
$$
考虑如何优化这个东西。
显然 $i - j$ 中 $0$ 的个数可以通过前缀和来优化,然后我们对于所有满足 $S_i == S_j$ 的条件的考虑一步步去找相邻两个的方案数。
可以记 $g_i$ 表示所有 $f_i$ 的和,记 $Lst_i$ 表示异或和为 $i$ 的上一个编号。
然后就有转移
$$
f_{s_i} += (Z_i - Z_{Lst_{s_i}}) \times g_{s_i}
$$
$$
g_{s_i} += f_{s_i}
$$
就是前面的所有 $f_{s_i}$ 都可以转移到当前的 $f_{s_i}$ ,并且要乘上这一个 $i$ 遇上一个之间所有 $0$ 的个数,因为都可以转移到。
然后做前缀和即可。
最后答案需要判断 $f_{s_n}$ 是否为 $0$ ,不为 $0$ 就直接取 $f_{s_n}$ 作为答案。
否则考虑加入后面的没取的 $0$ 造成的贡献,注意最后一个 $0$ 必须取才可以转移。
最后累加所有 $g_i$ 即可。
$Code;$
1 |
|