CF959F
题目大意:给定n个数,有Q次询问,每次询问由两个数l,x组成,表示前缀[1,l]构成的子序列有多少异或起来为x,个数%1e9+7
做法:考虑一个由x个数构成的线性基,如果这个线性基由Y个数构成,可以通过线性基得到z,那么x个数得到z的方案为2^(Y-x),不在线性基中的数随便选
然后就变成斯波题了,维护一个前缀线性基就好了
代码:
#include<bits/stdc++.h> #define Mod 1000000007 #define N 100005 using namespace std; int a[N],b[N][22],cnt[N],bin[N],n,Q,x,y; inline bool check(int x,int y){ for (int i=20;~i;i--){ if (y&(1<<i)){ if (!b[x][i]) return 0; y=y^b[x][i]; } } return y==0; } int main(){ scanf("%d%d",&n,&Q); for (int i=1;i<=n;i++) scanf("%d",&a[i]); for (int i=1;i<=n;i++){ for (int j=0;j<=20;j++) b[i][j]=b[i-1][j]; cnt[i]=cnt[i-1]; for (int j=20;~j;j--){ if (a[i]&(1<<j)){ if (!b[i][j]){b[i][j]=a[i];cnt[i]++;break;} else a[i]^=b[i][j]; } } }bin[0]=1; for (int i=1;i<=n;i++) bin[i]=1ll*bin[i-1]*2%Mod; while (Q--){ scanf("%d%d",&x,&y); if (!check(x,y)) puts("0"); else printf("%d\n",bin[x-cnt[x]]); } return 0; }