Brief explanation
-
Linear basis under xor:
Linear basis method:
From high position to low position, if the linear basis of control I position exists, then a[k]^=p[i]
Otherwise, p[i] = a[k];break;
Furthermore, the I-bit of the linear basis other than the linear basis p[i] is changed to 0, and the linear basis with the smallest element is obtained. Find the k-th small;
Note that when the element is redundant, 0 can be generated with exclusive or; otherwise, 0 cannot be generated.
If k is expressed in binary, it can XOR the corresponding linear basis.The concept of linear basis is similar to space expansion, that is, the whole space can be expanded to be different or operated by the least elements
Reference blog
Example HDU3949
code
#include <bits/stdc++.h> using namespace std; #pragma GCC optimize("O3") #define ll long long #define ull unsigned long long #define db(x) cout<<#x"=["<<(x)<<"]"<<endl #define CL(a,b) memset(a,b,sizeof(a)) #define fast() ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0) #define fr0(i,m) for(int i=0;i<m;i++) #define fr1(i,m) for(int i=1;i<=m;i++) //author:fridayfang //Date: July 7, 19 const double esp=1e-8; const int mod=1e9+7; const double pi=acos(-1); const int inf=0x3f3f3f3f; const int maxn = 1e4 + 5; const int maxm = 1e6+5; ll a[maxn]; ll p[64]; int to[100];// ll t,n,q; int getBase(){//Processing outgoing basis CL(p,0);//Clear 0 first. for(ll i=1;i<=n;i++){ for(int j=63;j>=0;j--){ if((a[i]>>j)&1){ if(!p[j]){p[j] = a[i]; break;} a[i]^=p[j]; } } } // Smaller linear basis int cnt = 0; for(int j=0;j<=63;j++){ if(!p[j]) continue; for(int i=j+1;i<=63;i++){ if((p[i]>>j)&1) p[i] = p[i]^p[j]; } to[cnt++]=j; } return cnt;//CNT is the number of linear bases to[0]...to[cnt-1] has the correct mapping } ll getK(ll k,int bound){//Minimum k except 0 int t = 0; ll tmp = k; ll ans = 0; while(tmp){ if(t>=bound) return -1; if(tmp&1) ans^=p[to[t]]; tmp = tmp>>1; t++; } return ans; } int main(){ fast();cin>>t; for(ll i=1;i<=t;i++){ cout<<"Case #"<<i<<":\n"; cin>>n; for(ll k=1;k<=n;k++) cin>>a[k]; int cnt = getBase(); int t = (cnt==(int)n)?0:1;//Unequal means there is redundancy, then it means 0; at this time, the k-1 of the k-th hour is small. cin>>q; ll k; for(ll s=1;s<=q;s++){ cin>>k; k-=t; cout<<getK(k,cnt)<<endl; } } return 0; }