Ehab has an array a of n integers. He likes the bitwise-xor operation and he likes to bother Mahmoud so he came up with a problem. He gave Mahmoud q queries. In each of them, he gave Mahmoud 2 integers l and x, and asked him to find the number of subsequences of the first l elements of the array such that their bitwise-xor sum is x. Can you help Mahmoud answer the queries?
A subsequence can contain elements that are not neighboring.
The first line contains integers n and q (1 ≤ n, q ≤ 105), the number of elements in the array and the number of queries.
The next line contains n integers a1, a2, ..., an (0 ≤ ai < 220), the elements of the array.
The next q lines, each contains integers l and x (1 ≤ l ≤ n, 0 ≤ x < 220), representing the queries.
For each query, output its answer modulo 109 + 7 in a newline.
5 5 0 1 2 3 4 4 3 2 0 3 7 5 7 5 8
4 2 0 4 0
3 2 1 1 1 3 1 2 0
4 2
The bitwise-xor sum of the empty set is 0 and the bitwise-xor sum of a set containing one element is that element itself.
思路:线性基。求出数组a的前缀线性基,那么对于询问l,x。判断x是否能由l处的前缀线性基表示,若不能则输出0;若能,则对于线性基里的数来说只有一种选法,然后非线性基里的数可选可不选,就算选了也可利用线性基将其异或补成x。
#include<bits/stdc++.h>
using namespace std;
const int MAX=1e5+10;
const int MOD=1e9+7;
typedef long long ll;
int s[MAX][21],num[MAX];
int POW(int n)
{
ll res=1,a=2;
while(n)
{
if(n&1)res=res*a%MOD;
a=a*a%MOD;
n/=2;
}
return res;
}
int check(int x,int y)
{
for(int i=20;i>=0;i--)
{
if(y&(1<<i))y^=s[x][i];
}
return y==0;
}
int add(int *p,int x)
{
for(int j=20;j>=0;j--)
{
if(x&(1<<j))
{
if(p[j]==0)
{
p[j]=x;
return 1;
}
else x^=p[j];
}
}
return 0;
}
int main()
{
int n,q;
cin>>n>>q;
memset(s,0,sizeof s);
memset(num,0,sizeof num);
for(int i=1;i<=n;i++)
{
for(int j=0;j<=20;j++)s[i][j]=s[i-1][j];
int x;
scanf("%d",&x);
num[i]=add(s[i],x);
num[i]+=num[i-1];
}
while(q--)
{
int l,x;
scanf("%d%d",&l,&x);
if(check(l,x)==0)puts("0");
else printf("%d\n",POW(l-num[l]));
}
return 0;
}