题意:给出N个数,再给出q次查询,每一次的查询在N个数中的值进行异或后第k小的值是多少!
这个线性基我也今天刚学,也只是在套模版,有些地方感觉有点难理解!
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long ll;
const int maxx=105;
ll a[maxx];
ll p[maxx];
int n,m;
int q;
void get_linear(ll n){
for(ll i=0;i<n;i++){
for(ll j=62;j>=0;j--){
if(a[i]>>j){
if(p[j]){
a[i]^=p[j];
}else{
p[j]=a[i];
break;
}
}
}
}
int r=0;
for(int j=0;j<=62;j++){
if(p[j]){
r++;
}
}
}
struct Linear_Basis{
ll b[maxx],nb[maxx],tot;
Linear_Basis(){
tot=0;
memset(b,0,sizeof(b));
memset(nb,0,sizeof(nb));
}
void clear(){
tot=0;
memset(b,0,sizeof(b));
memset(nb,0,sizeof(nb));
}
bool ins(ll x){//插入一个数
for(int i=62;i>=0;i--){
if(x&(1ll<<i)){
if(b[i]){
x^=b[i];
}else{
b[i]=x;
break;
}
}
}
return x>0;
}
ll Max(ll x){//求异或最大值
ll res=x;
for(int i=62;i>=0;i--){
res=max(res,res^b[i]);
}
return res;
}
ll Min(ll x){//求异或最小值
ll res=x;
for(int i=0;i<=62;i++){
if(b[i]){
res^=b[i];
}
}
return res;
}
void rebuild(){//重构化为对角矩阵 为求 Kth_MAX 做铺垫
for(int i=62;i>=0;i--){
for(int j=i-1;j>=0;j--){
if(b[i]&(1ll<<j)){
b[i]^=b[j];
}
}
}
for(int i=0;i<=62;i++){
if(b[i]){
nb[tot++]=b[i];
}
}
}
ll Kth_Min(ll k){//求第k小的数
//rebuild();
if(k>=(1ll<<tot)){
return -1;
}
ll res=0;
for(int i=62;i>=0;i--){
if(k&(1ll<<i)){
res^=nb[i];
}
}
return res;
}
}LB;
Linear_Basis merge(const Linear_Basis&n1,const Linear_Basis&n2){//合并两个线性基
Linear_Basis ret=n1;
for(int i=62;i>=0;i--){
if(n2.b[i]){
ret.ins(n2.b[i]);
}
}
return ret;
}
int main(){
int t;
scanf("%d",&t);
int count=1;
while(t--){
LB.clear();
bool index=true;
scanf("%d",&n);
for(int i=1;i<=n;i++){
ll x;
scanf("%lld",&x);
index&=LB.ins(x);
}
cout<<"Case #"<<count++<<":"<<endl;
scanf("%d",&q);
LB.rebuild();
for(int i=1;i<=q;i++){
ll x;
scanf("%lld",&x);
int tt=x-1+index;
cout<<LB.Kth_Min(tt)<<endl;
}
}
return 0;
}