//小心全局变量a数组会被改变
void cal(int n) {
cnt = 0;
memset(b, 0, sizeof(b));
for (int i = 0; i < n; ++i)
for (int j = MAX_BASE; j >= 0; --j)
if (a[i] >> j & 1) {
if (b[j]) a[i] ^= b[j];
else {
cnt++;
b[j] = a[i];
for (int k = j - 1; k >= 0; --k) if (b[k] && (b[j] >> k & 1)) b[j] ^= b[k];
for (int k = j + 1; k <= MAX_BASE; ++k) if (b[k] >> j & 1) b[k] ^= b[j];
break;
}
}
/*
printf("n = %d base:\n", n);
rep(i, 0, cnt){
printf("%d ", b[i]);
}
puts("");
*/
}
注意 b里面存的都是处理过的a, 和a不一样
https://blog.sengxian.com/algorithms/linear-basis
Codeforces 959 F Mahmoud and Ehab and yet another xor task
Discription
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 isx. Can you help Mahmoud answer the queries?
A subsequence can contain elements that are not neighboring.
Input
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.
Output
For each query, output its answer modulo 109 + 7 in a newline.
Examples
Input
5 5
0 1 2 3 4
4 3
2 0
3 7
5 7
5 8
Output
4
2
0
4
0
Input
3 2
1 1 1
3 1
2 0
Output
4
2
Note
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.
4、判断:
用线性基求一个数能否被xorxor出:从高到低,对该数每个是11的位置xx,将这个数异或上axax(注意异或后这个数为1的位置和原数就不一样了),若最终变为00,则可被异或出。当然需要特判00(在构造过程中看是否有p变为0即可)。例子:(11111,10001)(11111,10001)的线性基是a5=11111a5=11111,a4=01110a4=01110,要判断1111111111能否被xorxor出,1111111111 xorxor a5a5=0=0,则这个数后来就没有是11的位置了,最终得到结果为00,说明1111111111能被xorxor出。
#include<bits/stdc++.h>
#define rep(i, j, k) for (int i=j; i<k; i++)
//#define pii pair<int, int>
#define fi first
#define se second
using namespace std;
const int maxn = 1e5+5;
const int MAX_BASE = 20;
const int mod = 1e9 + 7;
int n, q, cnt, last;
int a[maxn], b[MAX_BASE], pow2[maxn];
struct Query{
int l, x, ans, id;
}query[maxn];
bool cmpl(Query a, Query b){
return a.l < b.l;
}
bool cmpid(Query a, Query b){
return a.id < b.id;
}
int check(int x){
for(int i = MAX_BASE-1; i >= 0; i--){ //从高位到低位
if ((x>>i) & 1) {
if (((b[i] >> i) & 1) == 0) return false;
x^=b[i];
if (!x) return true;
}
}
return true;
}
void insert(int n) {
for (int j = MAX_BASE-1; j >= 0; --j)
if (n >> j & 1) {
if (b[j]) n ^= b[j];
else {
cnt++;
b[j] = n;
for (int k = j - 1; k >= 0; --k) if (b[k] && (b[j] >> k & 1)) b[j] ^= b[k];
for (int k = j + 1; k <= MAX_BASE-1; ++k) if (b[k] >> j & 1) b[k] ^= b[j];
break;
}
}
}
int main(){
scanf("%d%d", &n, &q);
pow2[0] = 1;
rep(i, 1, n+1){
pow2[i] = pow2[i-1] * 2 % mod;
}
rep(i, 0, n){
scanf("%d", &a[i]);
}
rep(i, 0, q){
scanf("%d%d", &query[i].l, &query[i].x);
query[i].id = i;
}
sort(query, query+q, cmpl);
last = 0;
rep(i, 0, q){
rep(j, last, query[i].l){
insert(a[j]);
}last = query[i].l;
if (!check(query[i].x)){
query[i].ans = 0;
continue;
}
query[i].ans = pow2[query[i].l-cnt];
}
sort(query, query+q, cmpid);
rep(i, 0, q){
printf("%d\n", query[i].ans);
}
}