hdu 3949 XOR 求第K小異或值
Input First line of the input is a single integer T(T<=30), indicates there are T test cases.
For each test case, the first line is an integer N(1<=N<=10000), the number of numbers below. The second line contains N integers (each number is between 1 and 10^18). The third line is a number Q(1<=Q<=10000), the number of queries. The fourth line contains Q numbers(each number is between 1 and 10^18) K1,K2,......KQ.
Output For each test case,first output Case #C: in a single line,C means the number of the test case which is from 1 to T. Then for each query, you should output a single line contains the Ki-th smallest number in them, if there are less than Ki different numbers, output -1.
Sample Input 2 2 1 2 4 1 2 3 4 3 1 2 3 5 1 2 3 4 5
Sample Output Case #1: 1 2 3 -1 Case #2: 0 1 2 3 -1 Hint
//
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define bignum long long
const int maxn=11000;
//求a中第k小異或值(a[i]可單獨取)
bignum a[maxn];
int n;//0->n-1
int l;//線性基個數
//將a[i]寫成2進位制形式,化簡成標準行列式形式(左上角E,右下角0)
void Gauss(const int m=62)
{
l=0;
for(int i=m;i>=0;i--)//位數
{
int flag=0;
for(int j=l;j<n;j++)
{
if(a[j]&(1LL<<i))//1LL important
{
swap(a[l],a[j]);flag=1;break;
}
}
if(flag)
{
for(int j=0;j<n;j++)
{
if(j!=l&&(a[j]&(1LL<<i))) a[j]^=a[l];
}
l++;
}
}
}
bignum calc(bignum k,const int m=62)
{
//0特殊處理
if(l<n)//存在異或值為0
{
if(k==1) return 0;
else k--;
}
if(k>=(1LL<<l)) return -1;
bignum cnt=0;
for(int i=0;i<=m;i++)
{
if(k&(1LL<<i)) cnt^=a[l-i-1];
}
return cnt;
}
int main()
{
int ci,pl=1;scanf("%d",&ci);
while(ci--)
{
scanf("%d",&n);
for(int i=0;i<n;i++) scanf("%I64d",&a[i]);
Gauss();
int q;scanf("%d",&q);
printf("Case #%d:\n",pl++);
while(q--)
{
bignum k;scanf("%I64d",&k);
printf("%I64d\n",calc(k));
}
}
return 0;
}