[线性基] BZOJ 4269: 再见Xor

本文介绍了一种基于线性代数原理的算法——线性基,并详细解释了如何使用该算法解决特定问题。通过实例代码展示了如何实现线性基算法,并进行最大值查询的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

SolutionSolution

划水中。。迟早要完
显然要线性基。。
考虑求kk大。
对于基的每一个位置,因为其最高非零位就是位置标号,那看一下k的这一位是否为11,看是否要异或上(或者不异或)使得这一位得到的答案较大。

#include <bits/stdc++.h>
#define show(x) cerr << #x << " = " << x << endl
using namespace std;
typedef long long ll;
typedef pair<int, int> Pairs;

const int N = 101010;

inline char get(void) {
    static char buf[100000], *S = buf, *T = buf;
    if (S == T) {
        T = (S = buf) + fread(buf, 1, 100000, stdin);
        if (S == T) return EOF;
    }
    return *S++;
}
template<typename T>
inline void read(T &x) {
    static char c; x = 0; int sgn = 0;
    for (c = get(); c < '0' || c > '9'; c = get()) if (c == '-') sgn = 1;
    for (; c >= '0' && c <= '9'; c = get()) x = x * 10 + c - '0';
    if (sgn) x = -x;
}

struct linearBasis {
    int a[32];
    int siz;
    inline int size(void) {
        return siz;
    }
    inline int insert(int x) {
        for (int i = 30; ~i; i--)
            if (x >> i & 1) {
                if (!a[i]) {
                    a[i] = x; return ++siz;
                } else x ^= a[i];
            }
        return 0;
    }
    inline int query(int k) {
        int res = 0, cnt = siz;
        for (int i = 30; ~i; i--) {
            if (!a[i]) continue;
            --cnt;
            int tmp = max(res, res ^ a[i]);
            if (k >> cnt & 1) res = tmp;
            else res = tmp ^ a[i];
        }
        return res;
    }
} LB;
int n, x, mx;

int main(void) {
    freopen("1.in", "r", stdin);
    freopen("1.out", "w", stdout);
    read(n);
    while (n--) {
        read(x); LB.insert(x);
    }
    int L = 0, R = (1 << LB.size()) - 1, Mid, Ans;
    printf("%d ", mx = LB.query(R));
    while (L <= R) {
        int Mid = (L + R) >> 1;
        if (LB.query(Mid) < mx) L = (Ans = Mid) + 1;
        else R = Mid - 1;
    }
    printf("%d\n", LB.query(Ans));
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值