zoukankan      html  css  js  c++  java
  • 数学手法之线性基

    定义

    基:在线性代数中,基(也称为基底)是描述、刻画向量空间的基本工具。向量空间的基是它的一个特殊的子集,基的元素称为基向量。向量空间中任意一个元素,都可以唯一地表示成基向量的线性组合。如果基中元素个数有限,就称向量空间为有限维向量空间,将元素的个数称作向量空间的维数。

    同样的,线性基是一种特殊的基,它通常会在异或运算中出现,它的意义是:通过原集合S的某一个最小子集S1使得S1内元素相互异或得到的值域与原集合S相互异或得到的值域相同。

    性质

    1.线性基能相互异或得到原集合的所有相互异或得到的值。

    2.线性基是满足性质1的最小的集合

    3.线性基没有异或和为0的子集。

    证明:

    反证法:设线性基S={a1,a2...,an}

    若有子集a1^a2^...^at=0,则a1=a2^a3^...^at,则舍弃a1后一定能通过剩余的元素异或出所有需要a1参与异或的值。设Y=a1^X,因为{a1,a2,...,an}是一组线性基,X一定能由a2...an中相互异或得来。

    Y=a1^X=a2^a3^...^at^X,将X中在a2...at中出现的元素删去,在a2...at中未出现的元素加入,则也能异或得到Y,所以a1于线性基无用,与线性基是最小子集的定义矛盾。

    所以:线性基没有异或和为0的子集。

    写法Luogu P3812 【模板】线性基

    #include<bits/stdc++.h> //万能头文件 
    using namespace std;
    long long n,ans,a[51],b[51],m[52]; //数据是2^50,想开的更大也星 
    int main()
    {
    	ios::sync_with_stdio(0); //小优化,不用在意(雾) 
        cin>>n;
        m[0]=1; //预处理 
        for(int i=1;i<=51;++i)
        	m[i]=m[i-1]<<1;
        for(int i=1;i<=n;++i) //读入数据 
            cin>>a[i];
        //线性基标准模板 
        for(int i=1;i<=n;++i)
            for(int j=51;j>=0;--j)
                if(m[j]&a[i])
                    if(b[j]) 
    					a[i]^=b[j];
                    else 
    				{
    					b[j]=a[i];
    					break;
    				}
    	//贪心算答案 
        for(int i=52;i>=0;--i)
            if((ans^m[i])>ans) 
    			ans^=b[i];
    	//输出 
        cout<<ans;
        return 0;
    }
    
  • 相关阅读:
    Linux基础命令题(ps/ls + grep)
    Operator Overloading in C++
    C++中class和struct的区别
    poj1110double vision搜索
    poj1321棋盘递归搜索
    vim窗口分割/切换
    xclipmore about copy&paste命令行粘贴
    [转载]怎样花两年时间去面试一个人
    最优二叉查找树optimalBSTC++实现
    vim复制粘贴——系统剪贴板
  • 原文地址:https://www.cnblogs.com/yzhang-rp-inf/p/9439241.html
Copyright © 2011-2022 走看看