(Q:)这都是些什么东西?听起来就觉得很毒瘤难啊??
(A:)这就是一种反人类的工具。
先来下定义:
-
向量加法
对于两个向量(a=(a_1,a_2,dots,a_n),b=(b_1,b_2,dots,b_n)),有
[c=a+b=(a_1+b_1,a_2+b_2,dots,a_n+b_n) ] -
标量乘法
对于向量(a=(a_1,a_2,dots,a_n)),常数(b),有
[c=ab=(a_1b,a_2b,dots,a_nb) ] -
线性空间
设有(n)个向量({a_1,a_2,dots,a_n}),若向量(b=c_1a_1+c_2a_2+dots+c_na_n),其中(c_1,c_2,dots,c_n)为常数,则(b)可以由(a_1,a_2,dots,a_n)表出,称所有这样的(b)的集合为一个“线性空间”,(a_1,a_2,dots,a_n)为此线性空间的生成子集。
-
线性相关
若对于向量集合({a_1,a_2,dots,a_n}),存在(a_i)能被除(a_i)以外的(a_1sim a_n)表出,则称这些向量“线性相关”,不则称为“线性无关”。
-
基
基则是线性空间的线性无关生成子集,基的向量个数称为线性空间的维数。
-
秩
对于一个(N imes M)的矩阵,称矩阵的每一行为一个长度为(M)的行向量,所表示的线性空间的维数称为矩阵的秩(行秩)。同理可定义列向量和列秩。
(Q:)可以说人话吗?
嘛其实上面的东西用处不是很大,只是介绍一下正式一点。
举个例子(.jpg)
线性空间 (Rightarrow) 平面直角坐标系
线性相关 (Rightarrow) ((0,1,1)=(0,0,1)+(0,1,0))
基 (Rightarrow) ((1,0,0),(0,1,0),(0,0,1))即为一组基底((x,y,z)轴的单位)
秩 (Rightarrow) (3)
那么对于一个矩阵进行消元,剩下的显然构成一组基底。
-
模板题。
-
如何构造线性基?
设线性基第(i)位对应的数为(p_i)。
对每个数(a_j)从高位向低查询,若有第(k)位,则将(a_jxor)上(p_k),否则插入并(break)。
显然,一个数要么插入线性基,要么能被其他数(xor)而成。
- 如何查询最值?
弹性的从高到低遍历每一位,若(i)位为(0)则(xor)上(p_i)。
正确性显然 因为每一位不会在后面被改变,所以为(1)是最优的。
(So Easy...?)
时间复杂度 (O(nlog_2a))
空间复杂度 (O(log_2a))
代码:
#include <cstdio>
int n;
long long a,p[55];//各基底
int main()
{
scanf("%d",&n);
while(n--)
{
scanf("%lld",&a);
for(int i=51;i>=0;--i)
if(a>>i&1)
{if(p[i])a^=p[i];//已有对应基底
else p[i]=a,i=0;}//插入,结束
}
long long Ans=0;
for(int i=51;i>=0;--i)
if(!(Ans>>i&1))
Ans^=p[i];//贪心求解
printf("%lld
",Ans);
return 0;
}
(Q:)学了这个之后我们可以干什么呢?
(A:)我们可以切黑题 解决许多与(xor)有关的题目了。
以上。逃去刷题了