HDU 3949 XOR(线性基)

题意:给出一组数,求最小的第k个由这些数异或出来的数。

先求这组数的线性基。那么最小的第k个数显然是k的二进制数对应的线性基异或出来的数。

 

# include <cstdio>
# include <cstring>
# include <cstdlib>
# include <iostream>
# include <vector>
# include <queue>
# include <stack>
# include <map>
# include <set>
# include <cmath>
# include <algorithm>
using namespace std;
# define lowbit(x) ((x)&(-x))
# define pi acos(-1.0)
# define eps 1e-7
# define MOD 1024523
# define INF 1000000000
# define mem(a,b) memset(a,b,sizeof(a))
# define FOR(i,a,n) for(int i=a; i<=n; ++i)
# define FO(i,a,n) for(int i=a; i<n; ++i)
# define bug puts("H");
# define lch p<<1,l,mid
# define rch p<<1|1,mid+1,r
# define mp make_pair
# define pb push_back
typedef pair<int,int> PII;
typedef vector<int> VI;
# pragma comment(linker, "/STACK:1024000000,1024000000")
typedef long long LL;
int Scan() {
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
void Out(int a) {
    if(a<0) {putchar('-'); a=-a;}
    if(a>=10) Out(a/10);
    putchar(a%10+'0');
}
const int N=10005;
//Code begin...

LL a[N], b[70], q[N];
const int MAX_BASE=63;
int pos;
bool flag;

void cal(int n)
{
    FO(i,0,n) for (int j=MAX_BASE; j>=0; --j) {
        if (!(a[i]>>j)) continue;
        if (b[j]) {
            a[i]^=b[j];
            if (!a[i]) flag=true;
        }
        else {
            b[j]=a[i];
            for (int k=j-1; k>=0; --k) if (b[k]&&(b[j]>>k&1)) b[j]^=b[k];
            FOR(k,j+1,MAX_BASE) if (b[k]>>j&1) b[k]^=b[j];
            break;
        }
    }
}
int main()
{
    int T, n, Q;
    LL x;
    scanf("%d",&T);
    FOR(cas,1,T) {
        scanf("%d",&n); mem(b,0); flag=false; pos=-1;
        FO(i,0,n) scanf("%lld",a+i);
        cal(n); FOR(i,0,MAX_BASE) if (b[i]) b[++pos]=b[i];
        scanf("%d",&Q);
        printf("Case #%d:\n",cas);
        while (Q--) {
            scanf("%lld",&x);
            if (flag) --x;
            int wei=0;
            LL tmp=x;
            while (tmp) ++wei, tmp/=2;
            if (wei>pos+1) puts("-1");
            else {
                LL ans=0;
                FOR(i,0,pos) {
                    if (x&1) ans^=b[i];
                    x/=2;
                }
                printf("%lld\n",ans);
            }
        }

    }
    return 0;
}
View Code

 

posted @ 2017-05-11 22:13  free-loop  阅读(156)  评论(0编辑  收藏  举报