线性基模板 HDU 3949

线性基是哪里除以一堆数的异或的最值的情况的。

其实基底就是线性代数中的无关组,线性基应该是最小无关组。

最近也学习了一下,网上的博客也讲得很好,今天在这里写一个模板。

#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;
}
发布了130 篇原创文章 · 获赞 80 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/KXL5180/article/details/99051582