异或的技巧用的好还是很有用的。
原题链接:EOJ3329
给你N个数,输出满足异或和是质数的子集个数(允许有重复元素),答案可能很大,输出模 1e9+7 后的结果。
Examples
Input
|
|
Output
|
|
Note
3511,3671,4153,3511 xor 3671 xor 4153 都是质数,所以输出 4。
代码如下:
|
|
先用素数筛求出2到9000之间的所有素数。map记录每个数出现次数。dp【i】【j】表示从前i个不同的数中组成的所有集合中,能使得异或和的结果为j的集合个数(注意这里第i个数可以一个都不取)。为减小空间还用到了滚动数组。
dp[now][j] = ((dp[last][j^a[i]]*odd)%MOD+dp[last][j]*even)%MOD;
这句话的理解是关键,dp[now][j]
有两种来源,可以通过以下知识点来理解。
知识点补充: a^b^b = a , 也就是说,异或是可以抵消的,放到这里来说,假如我想知道x^a = b中的x,那么我只需要把b再^一下a就行了,这就是转移的关键. 那么,异或也有一个奇偶之分,就是^奇数个等于^一个,偶数个等于没^.所以转义方程的写法是那样。