Description
给出n个正整数,问这
Input
第一行一整数
Output
对于每次查询,输出这n个正整数选取非空子集异或得到的数集中第
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
Solution
求出线性基,假设有m个数字,把这
Code
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long ll;
const int maxn=10005;
int T,n,q,Case=1;
ll a[maxn],k,base[66];
int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(int i=0;i<n;i++)scanf("%I64d",&a[i]);
memset(base,0,sizeof(base));
for(int i=0;i<n;i++)
for(int j=62;j>=0;j--)
if((a[i]>>j)&1)
{
if(!base[j])
{
base[j]=a[i];
break;
}
else a[i]^=base[j];
}
for(int i=62;i>=0;i--)
if(base[i])
for(int j=i-1;j>=0;j--)
if((base[i]>>j)&1)base[i]^=base[j];
int m=0;
for(int i=0;i<=62;i++)
if(base[i])base[m++]=base[i];
printf("Case #%d:\n",Case++);
scanf("%d",&q);
while(q--)
{
scanf("%I64d",&k);
if(m!=n)k--;
if(k>=(1ll<<m))printf("-1\n");
else
{
ll ans=0;
for(int i=0;i<m;i++)
if((k>>i)&1)ans^=base[i];
printf("%I64d\n",ans);
}
}
}
return 0;
}

针对一组正整数,本文介绍了一种高效的算法来查询由这些数的所有非空子集通过异或运算产生的结果中第k小的数值。该算法利用线性基的概念,通过列变换和排序来解决此问题。
503

被折叠的 条评论
为什么被折叠?



