Codeforces-959F:Mahmoud and Ehab and yet another xor task && CDOJ-2057:简单异或(线性基)

F. Mahmoud and Ehab and yet another xor task
time limit per test
1 second
memory limit per test
512 megabytes
input
standard input
output
standard output

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.

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 a1a2...an (0 ≤ ai < 220), the elements of the array.

The next q lines, each contains integers l and x (1 ≤ l ≤ n0 ≤ x < 220), representing the queries.

Output

For each query, output its answer modulo 109 + 7 in a newline.

Examples
input
Copy
5 5
0 1 2 3 4
4 3
2 0
3 7
5 7
5 8
output
Copy
4
2
0
4
0
input
Copy
3 2
1 1 1
3 1
2 0
output
Copy
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.

思路:线性基。求出数组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;
}




猜你喜欢

转载自blog.csdn.net/mitsuha_/article/details/80665607