[算法模板]线性基

线性基

GavinZheng敲懒的。。。

menci大佬的线性基博客

模板代码引自menci:

struct LinearBasis
{
    long long a[MAXL + 1];

    LinearBasis()
    {
        std::fill(a, a + MAXL + 1, 0);
    }

    LinearBasis(long long *x, int n)
    {
        build(x, n);
    }

    void insert(long long t)
    {
        for (int j = MAXL; j >= 0; j--)
        {
            if (!t) return;
            if (!(t & (1ll << j))) continue;

            if (a[j]) t ^= a[j];
            else
            {
                for (int k = 0; k < j; k++) if (t & (1ll << k)) t ^= a[k];
                for (int k = j + 1; k <= MAXL; k++) if (a[k] & (1ll << j)) a[k] ^= t;
                a[j] = t;
                break;
            }
        }
    }

    // 数组 x 表示集合 S,下标范围 [1...n]
    void build(long long *x, int n)
    {
        std::fill(a, a + MAXL + 1, 0);

        for (int i = 1; i <= n; i++)
        {
            insert(x[i]);
        }
    }

    long long queryMax()
    {
        long long res = 0;
        for (int i = 0; i <= MAXL; i++) res ^= a[i];
        return res;
    }

    void mergeFrom(const LinearBasis &other)
    {
        for (int i = 0; i <= MAXL; i++) insert(other.a[i]);
    }

    static LinearBasis merge(const LinearBasis &a, const LinearBasis &b)
    {
        LinearBasis res = a;
        for (int i = 0; i <= MAXL; i++) res.insert(b.a[i]);
        return res;
    }
};

原文地址:https://www.cnblogs.com/GavinZheng/p/11067665.html

时间: 2024-11-11 20:47:58

[算法模板]线性基的相关文章

[P3812][模板]线性基

解题关键:求异或最大值.线性基模板题. 极大线性无关组的概念. 异或的值域相同. #include<cstdio> #include<cstring> #include<algorithm> #include<cstdlib> #include<iostream> #include<cmath> using namespace std; typedef long long ll; const int MAX_BASE=63; ll b

[模板]线性基

用途 处理关于子集的异或和的问题,比如子集异或和的最大值,或者能不能异或出某个数 原理 从一堆数中处理出一组线性无关(?)的数,使得这些数能异或出的数和原来能异或出的数相同 线性基中,以每个位置为最高位1的数(最多)只有一个,这样就保证了线性无关 做法 依次处理每个数,对于x,从大到小扫描它的每一位,当扫到第i位为1时: 若线性基中没有最高位为i的数,则把x插到线性基中,结束扫描 若有,则把x异或上那个数,继续做 这样做,如果一个数最终没有被插入线性基中,证明它已经能被线性基中的数表示 而插到线

算法模板——线性欧拉函数

实现功能:求出1-N的欧拉函数,然后应对若干个询问操作 其实就是个素数判定+欧拉函数性质的二合一 代码如下,我觉得应高不难懂,只要你知道欧拉函数的性质 var i,j,k,l,m,n:longint; a,b:array[0..10000005] of longint; procedure phi; var i,j:longint; begin m:=0;a[1]:=1; for i:=2 to n do begin if a[i]=0 then begin inc(m); b[m]:=i; a

浅谈线性基

几个概念或引理 概念1:数集的异或和:定义一个无符号整数集合S(注意,我们接下来讨论的集合均指由无符号整数为元素构成的集合),则S的异或和就是S中所有元素互相异或的结果. 概念2:张成:子集Ti ⊆  S且子集Ti异或和组成的集合K就是数集S的张成,记做K=span(S)就可以理解为S中取任意多个元素异或运算获得的值组成的集合就是S的张成K. 概念3:线性相关和线性无关: 线性相关: 设元素x∈S,数集去除元素x后的数集为S’,且满足x∈span(S’)即 span(S)=span(S’),就可

[洛谷3812]【模板】线性基

题目大意: 给你n个数,求这些数能异或出的数的最大值. 思路: 线性基模板. b中的数满足对于每个b[i],最高位在第i位. 构造方法就是对于每个数字,从高到低枚举每一个1,如果这一位对应的b[i]还没有,就把这个数作为b[i],如果有,就把这个数异或上b[i]. 考虑两个数a,b,它们能异或出来的数为0,a,b,a xor b,如果把b换成a xor b,它们能异或出来的数还是0,a,b,a xor b. 所以b能异或出来的值域和a能异或出来的值域相同. 最后能异或出的最大值可以用类似贪心的思

【模板】线性基

线性基就是一种可以维护异或和的东西,我还没太懂它到底有什么用,但是很好写,而且思路也很清晰,所以板子还是很简单的. 题干: 题目背景 这是一道模板题. 题目描述 给定n个整数(数字可能重复),求在这些数中选取任意个,使得他们的异或和最大. 输入输出格式 输入格式: 第一行一个数n,表示元素个数 接下来一行n个数 输出格式: 仅一行,表示答案. 输入输出样例 输入样例#1: 复制 2 1 1 输出样例#1: 复制 1 说明 1≤n≤50,0≤Si≤250 1 \leq n \leq 50, 0 \

P3812 【模板】线性基

P3812 [模板]线性基 理解 :线性基 类似于 向量的极大无关组,就是保持原来所有数的异或值的最小集合, 求解过程也类似,可以 O( 60 * n )的复杂度求出线性基,线性基有许多性质,例如 线性基 里面的数进行异或 的值域与原来所有数异或的值域相同. #include<bits/stdc++.h> using namespace std; #define ll long long #define maxn 123 ll n,a[maxn],ans,p[maxn]; void getji

HDU3949 线性基模板

Ac链接 给定n个数,求子集异或和的第k大.\(n\le10^5,a_i\le10^9\). 第一步肯定是构造线性基.设线性基的基底数量为k,那么子集异或和本质不同的个数为\(2^k\)(如果有为0的情况).其实求第k大很简单,你把k拆分成2进制,对应基底从左到右的每一位,如果为1就异或上去就行了.不过我们需要分为两种情况,一个是存在异或和为0的情况,一个是不存在的.如果不存在异或和为0,需要把k+1. #include<bits/stdc++.h> #define ll long long

线性基(模板)

这里是连接o(´^`)o 线性基性质: 1.原序列里面的任意一个数都可以由线性基里面的一些数异或得到.2.线性基里面的任意一些数异或起来都不能得到0 03.线性基里面的数的个数唯一,并且在保持性质一的前提下,数的个数是最少的 //#include<bits/stdc++.h> #include<iostream> #include<cstdio> #include<algorithm> #include<cmath> #include<cs