线性基是哪里除以一堆数的异或的最值的情况的。
其实基底就是线性代数中的无关组,线性基应该是最小无关组。
最近也学习了一下,网上的博客也讲得很好,今天在这里写一个模板。
#include "bits/stdc++.h"
using namespace std;
typedef long long ll;
const int vmx = 66;
ll a[66], p[66];
int zero, cnt;
void Insert(ll x) {
for (int i = 62; i >= 0; i--) {
if (x & (1LL << i)) {
if (!a[i]) {
a[i] = 1;
return;
} else x ^= a[i];
}
}
zero = 1;
};
bool check(ll x) {
for (int i = 62; i >= 0; i--) {
if (x & (1LL << i)) {
if (!a[i]) return false;
else x ^= a[i];
}
}
return true;
}
ll qmax() {
ll ret = 0;
for (int i = 62; i >= 0; i--) {
ret = max(ret, ret ^ a[i]);
}
return ret;
}
ll qmin() {
if (zero) return 0;
for (int i = 0; i <= 62; i--) {
if (a[i]) return a[i];
}
}
void rebuild() {
for (int i = 62; i >= 0; i--) {
for (int j = i - 1; j >= 0; j--) {
if (a[i] & (1LL << j)) a[i] ^= a[j];
}
}
for (int i = 0; i <= 62; i++) {
if (a[i]) p[cnt++] = a[i];
}
}
ll quKth(ll k) {
k -= zero;
if (!k) return 0;
ll ret = 0;
if (k >= (1LL << cnt)) return -1;
for (int i = 0; i < cnt; i++) {
if (k & (1LL << i)) ret ^= p[i];
}
return ret;
}
int main() {
return 0;
}
然后再来一道模板题,HDU3949,直接套班子就是了。另外HDU6579也是一道有难度的线性基
#include "bits/stdc++.h"
using namespace std;
const double eps = 1e-8;
#define reg register
#define lowbit(x) x&-x
#define pll pair<ll,ll>
#define pii pair<int,int>
#define fi first
#define se second
#define makp make_pair
int dcmp(double x) {
if (fabs(x) < eps) return 0;
return (x > 0) ? 1 : -1;
}
typedef long long ll;
typedef unsigned long long ull;
const ull hash1 = 201326611;
const ull hash2 = 50331653;
const int N = 10000 + 10;
const int M = 1000 + 10;
const int inf = 0x3f3f3f3f;
const ll mod = 1000000000 + 7;
ll a[N], d[66], p[66], cnt;
int flag = 0;
void Insert(ll x) {
for (int i = 62; i >= 0; i--) {
if (x & (1LL << i)) {
if (!d[i]) {
d[i] = x;
return;
} else x ^= d[i];
}
}
flag = 1;
}
void rebuild() {
for (int i = 62; i >= 0; i--) {
for (int j = i - 1; j >= 0; j--) {
if (d[i] & (1LL << j)) d[i] ^= d[j];
}
}
for (int i = 0; i <= 62; i++) {
if (d[i]) p[cnt++] = d[i];
}
}
ll query(ll k) {
k -= flag;
if (!k) return 0;
if (k >= (1LL << cnt)) return -1;
ll ret = 0;
for (int i = 0; i < cnt; i++) {
if (k & (1LL << i)) ret ^= p[i];
}
return ret;
}
int main() {
int T, n, q;
scanf("%d", &T);
for (int Case = 1; Case <= T; Case++) {
memset(d, 0, sizeof(d));
memset(p, 0, sizeof(p));
cnt = 0, flag = 0;
ll x;
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
scanf("%lld", &x);
Insert(x);
}
rebuild();
scanf("%d", &q);
printf("Case #%d:\n", Case);
while (q--) {
scanf("%lld", &x);
printf("%lld\n", query(x));
}
}
return 0;
}