首先考虑暴力的转移,当枚举到第 iii 个数时,我们尝试将之前所有的有效状态的 P,Q,RP,Q,RP,Q,R 均与 aia_iai 尝试去异或,然后检测合法性。于是就有:
la[{
0,0,0}] = 1;
for (int i = 1;i <= n;++i)
{
for (auto item : la)
{
node v = item.first;
int x = v.p,y = v.q,z = v.r;
if (y == z || (x ^ a[i]) == y || (x ^ a[i]) == z) dp[{
x ^ a[i],y,z}] += la[v];
if (x == z || (y ^ a[i]) == x || (y ^ a[i]) == z) dp[{
x,y ^ a[i],z}] += la[v];
if (x == y || (z ^ a[i]) == x || (z ^ a[i]) == y) dp[{
x,y,z ^ a[i]}] += la[v];
}
for (auto item : dp) dp[item.first] %= MOD;
la.clear ();la = dp;dp.clear ();
}
但这样显然会有很多冗余的转移以及判断,考虑异或的性质去优化。
回顾一下题面,对于一个数字只能选择 P,Q,RP,Q,RP,Q,R 中的一个去异或,那么处理完 aia_iai 后,P⊕Q⊕R=⊕j=1iaj=piP \oplus Q \oplus R = \oplus _{j = 1}^i a_j = p_iP⊕Q⊕R=⊕j=1iaj=pi。由于 P,Q,RP,Q,RP,Q,R 不能两两互异,此时设 (P,Q,R)(P,Q,R)(P,Q,R) 中相同的数为 xxx,由于 x⊕y⊕y=xx \oplus y \oplus y = xx⊕