2020辽宁省赛 xor(前缀和DP 异或性质)
2020辽宁省赛 xor
题意:
现在有一个长度为n的数组a。现在要将a拆分成若干个连续的子数组,要求每个连续的数组异或和都为x。请问有多少种拆分的方案。
思路:
容易推出转移方程
\[f_i=\sum f_j(当xorsum_i \oplus xorsum_j = x)
\]
由于我们知道异或的性质,\(a \oplus b = c\)等价于\(a = b \oplus c\),所以我们对公式稍作转换,可知,\(xorsum_j=xorsum_i \oplus x\)的时候,就可以直接转移过去。诶这是一个前缀和优化DP。为了方便做,我就用map存了一下,\(f[i]=map[sumxor_i \oplus x], map[sumxor_i] = f[i]\)。
实现:
#define int long long
const int mod = 1e9 + 7;
unordered_map<int, int> mp;
signed main()
{
int n, x;
scanf("%lld%lld", &n, &x);
int sum = 0; //异或和
mp[sum] = 1;
for(int i = 1; i <= n; i ++)
{
int t; scanf("%lld", &t);
sum ^= t;
mp[sum] = (mp[sum] + mp[sum ^ x]) % mod;
}
printf("%lld\n", mp[sum ^ x]);
}