HDU3949/AcWing210 XOR (高斯消元求线性基)
求第k小的异或和,用高斯消元求更简单一些。
1 //用高斯消元求线性基 2 #include3 using namespace std; 4 #define N 10100 5 typedef long long ll; 6 int n; 7 bool zero; 8 ll a[N]; 9 10 void Gauss(){//高斯消元求线性基 11 int i,k=1;//k标记当前是第几行 12 ll j=(ll)1<<62;//注意不是63,long long临界2^63-1 13 for(;j;j>>=1){ 14 for(i=k;i<=n;i++) 15 if(a[i]&j) break;//找到第j位是1的a[] 16 if(i>n) continue;//没有第j位是1的a[] 17 swap(a[i],a[k]); 18 for(int i=1;i<=n;i++) 19 if(i!=k && a[i]&j) a[i]^=a[k]; 20 k++; 21 } 22 k--; 23 if(k!=n) zero=true;//有全0的行 24 else zero=false; 25 n=k;//线性基中元素个数 26 } 27 28 ll Query(ll k){//第k小异或和 29 ll ans=0; 30 if(zero) k--; 31 if(!k) return 0;//此时最小异或和就是0 32 for(int i=n;i;i--){ 33 if(k&1) ans^=a[i]; 34 k>>=1; 35 } 36 if(k) return -1;//不存在第k小的异或和 37 return ans; 38 } 39 40 int main(){ 41 int cnt=0; 42 int T;scanf("%d",&T); 43 while(T--){ 44 printf("Case #%d:\n",++cnt); 45 scanf("%d",&n); 46 for(int i=1;i<=n;i++) scanf("%lld",&a[i]); 47 Gauss(); 48 int q;scanf("%d",&q); 49 while(q--){ 50 ll k; scanf("%lld",&k); 51 printf("%lld\n",Query(k)); 52 } 53 } 54 }