考虑按位统计,把
q
q
q 拆成不超过
O
(
log
q
)
O(\log q)
O(logq) 个
2
x
2^x
2x 形式的数之和
转化成不超过
O
(
log
q
)
O(\log q)
O(logq) 个形如下面的问题
有多少个子集的异或和在
[
2
k
×
a
,
2
k
×
(
a
+
1
)
−
1
]
[2^k\times a,2^k\times(a+1)-1]
[2k×a,2k×(a+1)−1] 范围内
也就是有多少个子集的异或和去掉最低
k
k
k 个二进制位之后为
a
a
a
将每个数除以
2
k
2^k
2k 后构建线性基即可计算出
复杂度
O
(
n
log
A
log
q
)
O(n\log A\log q)
O(nlogAlogq)
Code
#include<cmath>#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#define For(i, a, b) for (i = a; i <= b; i++)#define Rof(i, a, b) for (i = a; i >= b; i--)inlineintread(){int res =0;bool bo =0;char c;while(((c =getchar())<'0'|| c >'9')&& c !='-');if(c =='-') bo =1;else res = c -48;while((c =getchar())>='0'&& c <='9')
res =(res <<3)+(res <<1)+(c -48);return bo ?~res +1: res;}constint N =1e5+5, M =40, ZZQ =10086;int n, a[N], q, bas[M], m, ans =1;intqpow(int a,int b){int res =1;while(b){if(b &1) res =1ll* res * a % ZZQ;
a =1ll* a * a % ZZQ;
b >>=1;}return res;}voidins(int x){int i;
Rof (i,30,0){if(!((x >> i)&1))continue;if(bas[i]==-1)return(void)(bas[i]= x);else x ^= bas[i];}
m++;}boolcanbe(int x){int i, res =0;
Rof (i,30,0){if(bas[i]==-1)continue;if(((res >> i)&1)^((x >> i)&1)) res ^= bas[i];}return res == x;}intquery(int offset,int val){int i;
m =0;memset(bas,-1,sizeof(bas));
For (i,1, n)ins(a[i]>> offset);if(canbe(val))returnqpow(2, m);return0;}intmain(){int i;
n =read();
For (i,1, n) a[i]=read();
q =read();if(!q)return(void)puts("1"),0;
q--;
Rof (i,30,0)if((q >> i)&1)
ans =(ans +query(i,(q >> i)^1))% ZZQ;memset(bas,-1,sizeof(bas)); m =0;
For (i,1, n)ins(a[i]);if(canbe(q)) ans =(ans +qpow(2, m))% ZZQ;
std::cout << ans << std::endl;return0;}