牛客 - 17968 - xor序列 - 线性基

https://ac.nowcoder.com/acm/problem/17968
下面是错误的做法,因为题目要求必须使用x,而y在check的时候不一定用到等价于x的线性基来构成。
正确的做法是直接check(x^y),这样y已经使用了x,再看看能不能经过其他数表示。

因为异或是交换群。

#include<bits/stdc++.h>
using namespace std;
#define ll long long

const int MN=34;
ll a[MN+1],tmp[MN+1];
ll copya[MN+1];

bool flag;//该线性基能否表示0

//尝试向线性基中插入一个值
void ins(ll x,ll *lb) {
    for(int i=MN; ~i; i--)
        if(x&(1ll<<i))
            if(!lb[i]) {
                lb[i]=x;
                return;
            } else
                x^=lb[i];
    flag=true;
}

//判断该线性基能否表示x
bool check(ll x,ll *lb) {
    if(x==0)
        return flag;
    for(int i=MN; ~i; i--)
        if(x&(1ll<<i))
            if(!lb[i])
                return false;
            else
                x^=lb[i];
    return true;
}

int main() {
    int n;
    scanf("%d",&n);
    ll x,y;
    for(int i=1; i<=n; i++)
        scanf("%lld",&x),ins(x,a);

    int q;
    scanf("%d",&q);
    while(q--) {
        scanf("%lld%lld",&x,&y);
        for(int i=0; i<=MN; i++) {
            copya[i]=a[i];
        }
        ins(x,copya);
        if(check(y,copya)) {
            puts("YES");
        } else {
            puts("NO");
        }
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/Yinku/p/10757935.html