HDU 3949:XOR(高斯消元求线性基)

高斯消元求线性基,并且将k二进制拆分
线性基是个什么东西呢? [学习笔记]线性基

#include<cstdio>
#include<algorithm>
using namespace std;

typedef unsigned long long ll;
const int maxn=10000+100;

ll ans[maxn];
int n,ind;

void gauss(){

    for(int i=61,j;i>=0;i--){

        for(j=ind;j<=n;j++) if(ans[j]&(1ll<<i)) break;
        if(j<=n){

            swap(ans[j],ans[ind]);
            for(j=1;j<=n;j++) if(j!=ind && ans[j]&(1ll<<i)) ans[j]^=ans[ind];
            ind++;
        }
    }
}

int main(){

    int T,C=0;
    scanf("%d",&T);
    while(T--){

        printf("Case #%d:\n",++C);

        scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%llu",&ans[i]);
        ind=1;
        gauss();
        ind--;
        ll Max;
        if(ind<n) Max=(1ll<<ind); //有0 [1,2^ind -1]+[0,0] 
        else Max=(1ll<<ind)-1; //无0 [1,2^ind -1]

        int q;
        scanf("%d",&q);
        while(q--){

            ll k;
            scanf("%llu",&k);
            if(k>Max) {

                printf("-1\n");
                continue;
            }
            if(ind<n) k--; //集合里面的元素xor情况有0,但是线性基里面的元素xor情况不包括0,所以k--
            ll tmp=0;
            for(int i=1;i<=ind;i++) if(k&(1ll<<(ind-i))) tmp^=ans[i];  //将k二进制拆分,为什么^ans[i]是 1ll<<(in-1),好好想想(二进制)
            printf("%llu\n",tmp);
        } 
    }

}

猜你喜欢

转载自blog.csdn.net/qq_37960603/article/details/81215807