「线性基」学习小结

向量空间

向量空间亦称线性空间。

形式化的,我们定义一个向量空间\((P,V,+,\cdot)\)

其中 \(P\)是一个域,\(V\)是一个非空的集合,其中的集合称作向量,同时定义两种运算分别为向量加法和标量乘法

一个\(P\)上的向量空间\((P,V,+,\cdot)\),需满足以下8条公理(其中的\(u,v,w\in V\),\(a,b\)是标量):

  1. \(u+(v+w)=(u+v)+w\)
  2. \(u+v=v+u\)
  3. \(\exists\mathbf{0}\)\(s.t. \ \ v+\mathbf{0}=v\)
  4. \(\forall v\in V,\exists w\in V\)\(s.t.\) \(v + w = 0\)
  5. \(a(u+v)=au+av\)
  6. \((a+b)v=av+bv\)
  7. \(a(bv)=(ab) v\)
  8. \(\exists 1,s.t. \ 1 \cdot v=v\)

基(basis)

向量空间\(V\)的基是可以张成\(V\)的一个线性无关的向量组,其中的元素称作基向量。

异或运算&线性基

把一个数的二进制表示看成是一个向量
\[ \mathbf{a}_i=(d_n,...d_0) \]
假设向量\(\mathbf{a}_0,\mathbf{a}_1,...\mathbf{a}_m\),的张成空间是\(S\)

定义一个向量空间\(V=(\{ 0,1\} ,S,xor,\cdot)\)

\(ps:\)这里,我们是把异或当作加法

求法

如何求出\(V\)的一个基\(\mathfrak{B}\)

我们要做的:是扫描每一个向量\(\mathbf{a}_i\),如果它存在于其它向量的张成空间中,就把它去掉

如何判断每个向量能否被前面的向量张成得到?

我们利用高斯消元:

int a[MN],base[log_MN];
inline void calc()
{//n is the highest bitregister int i,j,k;for(i=0;i<=m;++i)for(j=n;~j;--j)if(a[i]>>j&1)//Scan every bit of a[I] from top to bottom{if(base[j]) a[i]^=base[j];else{//There's no vector for this bitbase[j]=a[i];/*Maintain a diagonal matrixfor(k=j-1;~k;--k) if(base[k]&&(base[j]>>k&1)) base[j]^=base[k];for(k=j+1;k<=n;++k) if(base[k]>>j&1) base[k]^=base[j];*/break;}}
}

复杂度是\(O(mn)\),若位数较多,通常采用bitset优化,复杂度是\(O(\frac{mn^2}{\omega})\)

可以发现,我们在维护一组向量\(base[]\),满足\(base_i\)的最高位时\(i\)

为了方便,通常只把它消成一个上三角矩阵

当然,你也可以把它消成一个对角线矩阵,满足每一位最多只存在于一个向量中

线性基的运用

在这里,我们不严谨地称一个向量<另一个向量

其实指的是,每个向量对应的数的大小比较

查询最值

贪心求最大值:

  1. 如果所求是对角线矩阵,直接将所有向量相加即可
  2. 如果所求的是上三角矩阵,从高到低遍历每个向量,若ans加上当前的向量会变大,就将其贪心的加上

最小值是线性基中最小的向量

查询第k小值

首先在去重的前提下。

首先我们求出对角线矩阵

那么,如果 \(k=(100101)_2\),我们所求的即为\(base_0 +base_2+base_5\)

也就是各位所对应的数Xor起来即可

查询和是第几大

如果在去重的前提下,和查询第k小差不多。

如果不在去重的前提下的话:

\(m\)为给出数的个数, \(\mathfrak{B}\)为所求线性基

结论:每个数都出现一样的次数,且这个次数为 \(2^{m - \vert \mathfrak{B}\vert}\)

证明:

所有不在线性基中的数的个数为 \(m - \vert \mathfrak{B}\vert\),我们任意选择它的一个子集 \(S\),对于 \(S\) 中的每个数 \(v\),有唯一的方式表达为 \(\mathfrak {B}\)中向量的线性组合。我们对于每个 \(v\),将这个线性组合中的向量都选上(一个向量选多次可以看作是次数对\(2\)取模后的结果),两个相同的数异或起来得到 \(0\),所以对于每个数 \(x\),我们都能找到至少\(2^{n - \vert \mathfrak{B}\vert}\) 种不同的选择方案,使得异或值为 \(x\)。又因为对于每个子集 \(S\),为了使得最终异或值为 \(x\),选择线性基中的向量的方案是唯一的,所以上界也是 \(2^{n - \vert \mathfrak{B}\vert}\)

(此结论同时出现在2019/2/24 福建四校联考中的T1)

总结

观察大佬博客Sengxian'blog后......

线性基的题型相对比较固定,看到下面的类型基本上都是线性基了:

  1. 最大异或和 (例题:luogu模板题)
  2. \(k\)大异或和/异或和是第几大 (例题:bzoj 2844)
  3. 求所有异或值的和 (例题:bzoj 3811)

线性基中的题目中还用到一个技巧:

  • 任意一条\(1\)\(n\) 的路径的异或和,都可以由任意一条 \(1\)\(n\) 路径的异或和与图中的一些环的异或和来组合得到。(例题:bzoj 2115)

这便是线性基的全部东西了。

Code

洛谷P3812

#include<bits/stdc++.h>
#define ll long long
using namespace std;
inline ll read()
{ll x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}return x*f;
}
#define MN 55
ll n,base[MN],ans;
inline void insert(ll x)
{register int i,j;for(i=50;~i;--i)if(x>>i&1){if(base[i]) x^=base[i];else{base[i]=x;for(j=i-1;~j;--j)if(base[j]&&(base[i]>>j&1))base[i]^=base[j]; for(j=i+1;j<=50;++j)if(base[j]>>i&1)base[j]^=base[i];break;}}
}
int main()
{n=read();register int i;for(i=1;i<=n;++i) insert(read()); for(i=0;i<=50;++i) ans^=base[i];return 0*printf("%lld\n",ans);
} 

bzoj 2115 Xor

link

dfs出所有的环

求出它们的线性基

#include<bits/stdc++.h>
#define ll long long
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
inline ll read()
{ll x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}return x*f;
}
const int MN=200005,mN=50005,_=61; 
ll a[MN],tp,dfn[mN],dind,Xor[mN],b[_];
struct edge{int to;ll w;int nex;}e[MN<<1];
int N,M,hr[mN],en;
ll ans=0;
inline void ins(int x,int y,ll w)
{e[++en]=(edge){y,w,hr[x]};hr[x]=en;e[++en]=(edge){x,w,hr[y]};hr[y]=en;
}
inline void tj(int x,int f)
{register int i;dfn[x]=++dind;for(i=hr[x];i;i=e[i].nex)if(e[i].to^f){if(!dfn[e[i].to]) Xor[e[i].to]=Xor[x]^e[i].w,tj(e[i].to,x);else a[++tp]=Xor[x]^Xor[e[i].to]^e[i].w;}
}
inline void calc()
{register int i,j,k;for(i=1;i<=tp;++i)for(j=_-1;~j;--j)if(a[i]>>j&1){if(b[j]) a[i]^=b[j];else{b[j]=a[i];break;}}ans=Xor[N];for(i=_-1;~i;--i) if((ans^b[i])>ans) ans^=b[i];
}
int main()
{N=read();M=read();int x,y;while(M--) x=read(),y=read(),ins(x,y,read());tj(1,0);calc();return 0*printf("%lld\n",ans);
}

2019福建四校联考T1

link~

首先,容斥一下,转而求异或值为1的个数
\[ans=(2^n-1)(2^m-1)-num1\]
然后,对于一行,如果这一行的异或值不为0,它总有\(2^{m-1}\)个选法,使得选出的点的异或值是1(易证)
把每行当做一个数,我们只需要求出有哪些行的异或值为0
\[num1=2^{m-1}*(2^n-cnt0)\]
我们求出线性基,根据线性基的性质,异或值为0的个数一定是\(2^{n - \vert \mathfrak{B}\vert}\)

/*
2019/2/26 15:21
*/
#include<bits/stdc++.h>
#define ll long long
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
inline int read()
{int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}return x*f;
}
const ll mod=998244353,MN=2005;
std::bitset<MN> a[MN],base[MN];
int N,M,B;
ll ans;
inline void calc()
{register int i,j,k;for(i=1;i<=N;++i)for(j=M-1;~j;--j)if(a[i][j]){if(base[j].count()) a[i]^=base[j];else{base[j]=a[i];break;}}for(i=0;i<M;++i) if(base[i].count()) ++B;
}
inline ll fpow(ll x,int m)
{ll r=1;for(;m;m>>=1,x=1ll*x*x%mod) if(m&1) r=1ll*r*x%mod;return r;
}
int main()
{freopen("password.in","r",stdin);freopen("password.out","w",stdout);N=read();M=read();register int i,j;for(i=1;i<=N;++i)for(j=0;j<M;++j) a[i][j]=read()==1;calc();ans=(1ll*(fpow(2,N)-1)*(fpow(2,M)-1)%mod+mod)%mod;ans-=(1ll*fpow(2,M-1)*(fpow(2,N)-fpow(2,N-B)+mod)%mod)%mod;ans+=mod,ans%=mod;return 0*printf("%lld\n",ans);
}

暂时咕咕咕。


Blog来自PaperCloud,未经允许,请勿转载,TKS!

转载于:https://www.cnblogs.com/PaperCloud/p/10428084.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/275790.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ux体验网站 英国_定义网站图像时的UX注意事项

ux体验网站 英国As the saying goes —俗话说 - “A picture is worth a thousand words.”“一张图片胜过千言万语。” When creating content on the web, it’s often recommended to be using high-quality imageries and making sure that the images serve its purpose …

iconfont 支持全新的彩色字体图标

大家好&#xff0c;我是若川。iconfont我相信大家都用过&#xff0c;而现在支持全新的彩色字体图标了。这是第二次转载&#xff0c;上一次的好文是2020 前端技术发展回顾。点击下方卡片关注我、加个星标学习源码整体架构系列、年度总结、JS基础系列一直以来&#xff0c;Web 中想…

回文算法java实现_java算法题:最长回文串

LeetCode: 给定一个包含大写字母和小写字母的字符串&#xff0c;找到通过这些字母构造成的最长的回文串。在构造过程中&#xff0c;请注意区分大小写。比如"Aa"不能当做一个回文字符串。注 意:假设字符串的长度不会超过 1010。思路&#xff1a;利用hashset&#xff0…

Spring校验@RequestParams和@PathVariables参数

我们在写Rest API接口时候会用到很多的RequestParam和PathVariable进行参数的传递&#xff0c;但是在校验的时候&#xff0c;不像使用RequestBody那样的直接写在实体类中&#xff0c;我们这篇文章讲解一下如何去校验这些参数。 依赖配置 要使用Java Validation API&#xff0c;…

出色的社区网站_《最后的我们》中出色的制作系统

出色的社区网站游戏设计分析 (GAME DESIGN ANALYSIS) The Last of Us became an instant classic the day it was released, back in 2013. At the sunset of the sixth console generation, it felt like Naughty Dog managed to raise the bar in all critical areas of game…

入坑 Electron 开发跨平台桌面应用

‍作为一个跨平台的桌面应用开发框架&#xff0c;Electron 的迷人之处在于&#xff0c;它是建立在 Chromium 和 Node.js 之上的 —— 二位分工明确&#xff0c;一个负责界面&#xff0c;一个负责背后的逻辑&#xff0c;典型的「你负责貌美如花&#xff0c;我负责赚钱养家」。上…

Google 拼音会导致卡 Ctrl 键?

如果你使用 Windows 7 系统&#xff0c;并同时安装了 Google 输入法&#xff0c;那么 Firefox 启动时、WoW 时一定也常遇到卡住 Ctrl 键的问题。 今天仔细搜索了下&#xff0c;传说将输入法中“Ctrl键快速定位”关闭即可&#xff0c;有待验证&#xff0c;先记录着…转载于:http…

java 接口编程_JAVA面向接口编程

一、什么是面向接口编程要正确地使用Java语言进行面向对象的编程&#xff0c;从而提高程序的复用性&#xff0c;增加程序的可维护性、可扩展性&#xff0c;就必须是面向接口的编程。面向接口的编程就意味着&#xff1a;开发系统时&#xff0c;主体构架使用接口&#xff0c;接口…

不仅仅是手机,MWC现全球首例 5G NR 商用部署

近日&#xff0c;MWC大会在在巴塞罗那举行&#xff0c;5G折叠手机和5G部署进度成为这届大会的重点。除了华为与三星发布的折叠手机外&#xff0c;本届大会另一个值得关注的要点是三星和赛灵思宣布推进5G NR 商用部署在韩国落地&#xff0c;这应该是全球首例 5G 新无线电 (NR) 商…

小程序 显示细线_精心设计:高密度显示器上的细线

小程序 显示细线Despite the many benefits of Retina displays, there is one clear drawback that must be considered when designing for high-density screens:尽管Retina显示器具有许多优点&#xff0c;但在设计高密度屏幕时仍必须考虑一个明显的缺点&#xff1a; 必须避…

React 入门手册

大家好&#xff0c;我是若川。推荐这篇可收藏的React入门手册。也推荐之前一篇类似的文章《如何使用 React 和 React Hooks 创建一个天气应用》。点击下方卡片关注我、加个星标React 是目前为止最受欢迎的 JavaScript 框架之一&#xff0c;而且我相信它也是目前最好用的开发工具…

函数04 - 零基础入门学习C语言35

第七章&#xff1a;函数04 让编程改变世界 Change the world by program 上节课的练习简单讲解,给力&#xff01;&#xff01; 1.自己实现pow()函数并尝试验证…… 2.猜想下sqrt()函数的原理并尝试编程……&#xff08;暂时只要求整型数据&#xff09; 3.编写一个用来统…

java数据结构与算法_清华大学出版社-图书详情-《数据结构与算法分析(Java版)》...

前 言数据结构是计算机程序设计重要的理论技术基础&#xff0c;它不仅是计算机学科的核心课程&#xff0c;而且已经成为计算机相关专业必要的选修课。其要求是学会分析、研究计算机加工的数据结构的特性&#xff0c;初步掌握算法的时间和空间分析技术&#xff0c;并能够编写出结…

根号 巴比伦_建立巴比伦卫生设计系统

根号 巴比伦重点 (Top highlight)In this post I’ll explain the first phase of creating our Babylon DNA, the design system for Babylon Health, and how we moved the Babylon design team from Sketch to Figma.在这篇文章中&#xff0c;我将解释创建巴比伦DNA的第一阶…

《Migrating to Cloud-Native Application Architectures》学习笔记之Chapter 2. Changes Needed

2019独角兽企业重金招聘Python工程师标准>>> Cultural Change 文化变革 A great deal of the changes necessary for enterprise IT shops to adopt cloud-native architectures will not be technical at all. They will be cultural and organizational changes t…

前端,你要知道的SEO知识

大家好&#xff0c;我是若川。三天假期总是那么短暂&#xff0c;明天就要上班了。今天推荐一篇相对简单的文章。点击下方卡片关注我、加个星标之前有同学在前端技术分享时提到了SEO&#xff0c;另一同学问我SEO是什么&#xff0c;我当时非常诧异&#xff0c;作为前端应该对SEO很…

编制网站首页的基本原则

编制网站首页的基本原则如下&#xff1a; 1、编制网站首页的超文本文档的组织结构应清晰&#xff0c;条理分明&#xff0c;重点突出&#xff0c;可读性强&#xff0c;尽可能吸引用户的注意力。 2、说明文字应简明扼要&#xff0c;切中要害&#xff0c;每项内容介绍尽可能简单明…

MySQL数据库语句总结

增insert into -- 删 delete from -- 改 update table名字 set -- 查 select * from -- 一&#xff0e;SQL定义 SQL&#xff08;Structure Query Language&#xff09;结构化查询语言&#xff1a; &#xff08;一&#xff09;DDL&#xff08;Data Definition Language&#…

高安全性同态加密算法_坏的同态性教程

高安全性同态加密算法I was going to write at length about the issues I see in neumorphism and why this trend should be avoided. I know any attempt to guide my most impressionable colleagues away from it, will end up being failing because this fad is going t…

前端容易忽略的 debugger 调试技巧

大家好&#xff0c;我是若川。我们日常开发碰到的很多问题&#xff0c;通过 debugger 都能快速定位问题&#xff0c;所以推荐这篇大家容易忽略的调试技巧。会定位问题&#xff0c;可以节省很多时间。也就是我经常说的工欲善其事&#xff0c;必先利其器。也是为什么我经常强调调…