解题思路:先离线处理,按照l从小到大排序。然后依次将a数组中的数插入到线性基中,如果个数达到了l,判断x是否可以由线性基中的数异或得到。如果能那么答案就是2l-cnt,l表示已经插入了多少个数,cnt表示线性基中有几个非0的数。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double lf;
typedef unsigned long long ull;
typedef pair<int,int>P;
const int inf = 0x7f7f7f7f;
const double INF = 1e16;
const int N = 1e5+7;
const ll mod = 1e9+7;
const double PI = 3.1415926535;
const double eps = 1e-4;
inline int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;
}
inline string readstring(){
string str;char s=getchar();while(s==' '||s=='\n'||s=='\r'){s=getchar();}while(s!=' '&&s!='\n'&&s!='\r'){str+=s;s=getchar();}return str;
}
int random(int n){
return (int)(rand()*rand())%n;
}
ll a[N];
ll b[100];
ll ans[N];
struct node{
int id;
int l;
ll x;
}c[N];
bool cmp(node a,node b){
return a.l < b.l;
}
void Insert(ll x){
for(int i = 63;i >= 0;i--){
if(x&(1ll<<i)){
if(b[i]) x ^= b[i];
else {
b[i] = x;
break;
}
}
}
}
bool check(ll x){
for(int i = 63;i >= 0;i--){
if(x&(1ll<<i)){
if(b[i]) x ^= b[i];
else {
return false;
}
}
}
return true;
}
int fun(){
int ret = 0;
for(int i = 63;i >= 0;i--){
if(b[i]) ret++;
}
return ret;
}
ll funn(int cnt){
ll ans = 1;
ll a = 2ll;
if(cnt < 0) return ans;
while(cnt){
if(cnt&1) ans = (ans*a)%mod;
a = (a*a)%mod;
cnt >>= 1;
}
return ans;
}
int main(){
// srand((unsigned)time(NULL));
int n = read(),q = read();
for(int i = 1;i <= n;i++){
cin >> a[i];
}
for(int i = 1;i <= q;i++){
c[i].id = i;
cin >> c[i].l>> c[i].x;
}
sort(c+1,c+1+q,cmp);
int k = 1;
for(int i = 1;i <= n;i++){
Insert(a[i]);
while(k <= q && c[k].l == i){
if(check(c[k].x)){
int p = i-fun();
ans[c[k].id] = funn(p);
}
k++;
}
}
for(int i = 1;i <= q;i++){
cout<<ans[i]<<endl;
}
return 0;
}