题目大意:给出n个数,可以选择任意个异或,求排名第K的数
题解:高斯消元求线性基
线性基
线性基异或得到的子集与原数异或得到的子集是相同的。
而且线性基从高到低排列的,所以在求解第K大之类的问题时可以直接对k进行二进制分解,将1对应位置的基底异或得到答案。
#include
#include
#include
#include
#include
#define LL long long
#define N 11003
using namespace std;
int n,m,T,zero,tot;
LL b[N],a[N];
void gauss()
{
tot=zero=0;
for (LL i=b[60];i;i>>=1){
int j=tot+1;
while (!(i&a[j])&&j<=n) j++;
if (j==n+1) continue;
tot++;
swap(a[tot],a[j]);
for (int k=1;k<=n;k++)
if (k!=tot&&(a[k]&i)) a[k]^=a[tot];
}
if (tot!=n) zero=1;
}
LL solve(LL x)
{
x-=(LL)zero; LL ans=0;
if (!x) return 0;
if (x>=b[tot]) return -1;
for (int i=1;i<=tot;i++)
if (x&(b[tot-i])) ans^=a[i];
return ans;
}
int main()
{
freopen("a.in","r",stdin);
freopen("my.out","w",stdout);
scanf("%d",&T);
b[0]=1;
for (int i=1;i<=60;i++) b[i]=b[i-1]*2;
for (int t=1;t<=T;t++){
scanf("%d",&n);
printf("Case #%d:\n",t);
memset(a,0,sizeof(a));
for (int i=1;i<=n;i++) scanf("%I64d",&a[i]);
gauss();
//for (int i=1;i<=tot;i++) cout<
你可能感兴趣的:(高斯消元)