[CF959F]Mahmoud and Ehab and yet another xor task题解
搞n个线性基,然后每次在上一次的基础上插入读入的数,前缀和线性基,或者说珂持久化线性基。
然后一个num数组记录当时线性基里有多少数
然后每次前缀操作一下就珂以了
代码
#include <cstdio>
#define ll long long
const ll MOD = 1e9+7;
ll read(){
ll x = 0; int zf = 1; char ch = ' ';
while (ch != '-' && (ch < '0' || ch > '9')) ch = getchar();
if (ch == '-') zf = -1, ch = getchar();
while (ch >= '0' && ch <= '9') x = x * 10 + ch - '0', ch = getchar(); return x * zf;
}
ll base[100005][25];
ll bit[100005];
int num[100005];
inline bool insert(int pos, ll x, int &num){
for (int i = 20; ~i; --i)
if (x & (1ll << i))
if (!base[pos][i]){
base[pos][i] = x;
++num;
break;
}
else
x ^= base[pos][i];
return (x > 0);
}
inline ll judge(int pos, ll x){
for (int i = 20; ~i; --i){
if ((1ll << i) & x){
if (!base[pos][i])
return 0;
x ^= base[pos][i];
}
}
return (x == 0);
}
int main(){
int n = read(), q = read();
bit[0] = 1;
for (int i = 1; i <= n; ++i)
bit[i] = (bit[i - 1] << 1ll) % MOD;
for (int i = 1; i <= n; ++i){
int x = read();
for (register int j = 20; ~j; --j) base[i][j] = base[i - 1][j];
num[i] = num[i - 1];
insert(i, x, num[i]);
}
for (int i = 0; i < q; ++i){
int l = read(), x = read();
if (!judge(l, x))
printf("0\n");
else
printf("%d\n", bit[l - num[l]]);
}
return 0;
}