[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;
}
posted @ 2019-05-20 19:25  LinZhengmin  阅读(197)  评论(0编辑  收藏  举报

Contact with me