线性基
在https://blog.csdn.net/a_forever_dream/article/details/83654397这个博客学习的
看完了博客虽然还是不能完全理解线性基,但是大概懂了是怎么用的
1.求一个序列的最大/最小异或
2.求一个序列第k小异或
下面是一些入门题:
To xor or not to xor SGU - 275
求n个数的最大异或
#include <cstdio>
long long d[70];
int main() {
int n;
scanf("%d", &n);
long long a, ans = 0;
for(int i = 0; i < n; i++) {
scanf("%lld", &a);
for(int j = 60; j >= 0; j--) {
if(a & (1LL << j)) {
if(d[j]) a ^= d[j];
else {
d[j] = a;
break;
}
}
}
}
for(int i = 60; i >= 0; i--) {
if((ans ^ d[i]) > ans) ans ^= d[i];
}
printf("%lld
", ans);
return 0;
}
#include <cstdio>
#include <algorithm>
using std::sort;
typedef long long LL;
struct node
{
LL a, b;
}G[1010];
bool cmp(node x, node y) {
return x.b > y.b;
}
LL d[110];
int main() {
int n;
LL ans = 0;
scanf("%d", &n);
for(int i = 0; i < n; i++) {
scanf("%lld %lld", &G[i].a, &G[i].b);
}
sort(G, G +n, cmp);
for(int i = 0; i < n; i++) {
for(int j = 60; j >= 0; j--) {
if(G[i].a & (1LL << j)) {
if(d[j]) G[i].a ^= d[j];
else {
d[j] = G[i].a;
ans += G[i].b;
break;
}
}
}
}
printf("%lld
", ans);
return 0;
}
#include <cstdio>
typedef long long LL;
LL d[110];
int main() {
int n, m;
scanf("%d %d", &n, &m);
while(m--) {
char s[110];
LL a = 0;
scanf("%s", s);
for(int i = 0; i < n; i++) {
if(s[i] == 'O') {
a += (1LL << (n - i - 1));
}
}
//printf("aa %lld
", a);
for(int i = 60; i >= 0; i--) {
if(a & (1LL << i)) {
if(d[i]) a ^= d[i];
else {
d[i] = a;
break;
}
}
}
}
int cnt = 0;
for(int i = 0; i <= 60; i++) {
if(d[i]) cnt++;
}
printf("%lld
", (1LL << cnt) % 2008);
return 0;
}
t组数据,n个数的序列,q组询问第k小的异或值。
#include <cstdio>
#include <cstring>
typedef long long LL;
LL d[70];
int main() {
int t;
scanf("%d", &t);
for(int k = 1; k <= t; k++) {
printf("Case #%d:
", k);
memset(d, 0, sizeof(d));
int n;
LL a;
scanf("%d", &n);
for(int i = 0; i < n; i++) {
scanf("%lld", &a);
for(int j = 60; j >= 0; j--) {
if(a & (1LL << j)) {
if(d[j]) a ^= d[j];
else {
d[j] = a;
break;
}
}
}
}
int cnt = 0;
for(int i = 0; i <= 60; i++) {
if(d[i]) cnt++;
}
//printf("cnt %d
", cnt);
for(int i = 1; i <= 60; i++) {
for(int j = 1; j <= i; j++) {
if(d[i] & (1LL << (j - 1))) d[i] ^= d[j-1];
}
}
int q;
scanf("%d", &q);
while(q--) {
scanf("%lld", &a);
if(a == 1 && cnt < n) {
printf("0
");
continue;
}
if(cnt < n && (1LL << cnt) < a) {
printf("-1
");
continue;
}
if(cnt == n && (1LL << cnt) <= a) {
printf("-1
");
continue;
}
LL ans = 0;
if(cnt < n) a--;
for(int i = 0; i <= 60; i++) {
if(d[i]) {
if(a % 2 == 1) ans ^= d[i];
a /= 2;
}
}
printf("%lld
", ans);
}
}
return 0;
}