【BZOJ 4269】再见Xor
zky学长提供的线性基求法:
for(int i=1;i<=n;i++) for(int j=64;j>=1;j--) { if(a[i]>>(j-1)&1) { if(!lb[j]){lb[j]=a[i];break;} else a[i]^=lb[j]; } }
Gauss消元求线性基的方法:
#include<cstdio> #include<cstring> #include<algorithm> #define read(x) x=getint() using namespace std; const int N = 100003; int getint() { int k = 0, fh = 1; char c = getchar(); for(; c < '0' || c > '9'; c = getchar()) if (c == '-') fh = -1; for(; c >= '0' && c <= '9'; c = getchar()) k = (k << 1) + (k << 3) + c - '0'; return k * fh; } int n, a[N]; void Gauss() { int tmp = 0, i; for(int j = 1 << 30; j; j >>= 1) { for(i = tmp + 1; i <= n; ++i) if (a[i] & j) break; if (i > n) continue; swap(a[++tmp], a[i]); for(i = 1; i <= n; ++i) if (i != tmp && a[i] & j) a[i] ^= a[tmp]; } n = tmp; } int main() { read(n); for(int i = 1; i <= n; ++i) read(a[i]); Gauss(); int ans = 0; for(int i = 1; i <= n ;++i) ans ^= a[i]; printf("%d %d\n", ans, ans ^ a[n]); return 0; }
没了
NOI 2017 Bless All