HDU 3949 XOR(线性基)
题意:给出一组数,求最小的第k个由这些数异或出来的数。
先求这组数的线性基。那么最小的第k个数显然是k的二进制数对应的线性基异或出来的数。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
# 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; }