[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;
}

猜你喜欢

转载自www.cnblogs.com/linzhengmin/p/10895995.html