所以说这种神玩意我怎么可能自己研究嘛,都是搬运的,出处详见参考资料
定义 (F,V,+,⋅) 为向量空间,其中 F 为域, V 为集合, V 中元素称为向量, + 为向量加法, ⋅ 为标量乘法,且运算满足 8 条公理(见维基百科)。
对于向量空间中 V 上 n 个元素的向量组 (v1,v2,…,vn) , 若存在不全为 0 的数 ai∈F , 满足
对于向量空间中 V 上 n 个元素的向量组 (v1,v2,…,vn) , 其线性组合是如下形式的向量
一组向量 线性无关 等价于 没有向量可用有限个其他向量的 线性组合 所表示.
对于向量空间中 V 上 n 个元素的向量组 (v1,v2,…,vn) ,其所有线性组合所构成的集合称为 (v1,v2,…,vn) 的张成,记为 span(v1,v2,…,vn) .
若向量空间 V 中向量组 B 既是线性无关的又可以张成 V ,则称其为 V 的基。
B 中的元素称为基向量。如果基中元素个数有限,就称向量空间为有限维向量空间,将元素的个数称作向量空间的维数。
设 B 是向量空间 V 的基。则 B 具有以下性质:
第三点尤其重要,感性的理解,基就是向量空间中的一个子集,它可以通过唯一的线性组合,来张成向量空间中所有的向量,这样就可以大大的缩小我们向量空间的大小。
如果 (v1,v2,…,vn) 在 V 中是线性相关的,并且 v1≠0 , 则有至少一个 j∈{2,…,m} 使得下列成立:
证明
设 (v1,v2,…,vn) 在 V 中是线性相关的,并且 v1≠0 , 则有不全为 0 的 a1,a2,…,an∈F ,使得
a1v1+a2v2+⋯+amvm=0
a2,a3,…,an 不会全为 0 (因为 v1≠0 )。设 j 是 {2,…,m} 中使得 aj≠0 的最大者,那么
vj=−a1ajv1−a2ajv2−⋯−aj−1ajvj−1这就有 1 成立.
为了证明 2,设 u∈span(v1,…,vn) , 则存在 c1,c2,…,cn∈F , 使得
u=c1v1+c2v2+⋯+cnvn
在上面的等式中,可以用之前的等式右边来代替 vj . 这样 u 包含于从 (v0,v1,…,vn) 去掉第 j 项的张成,因而 2 成立。
设集合 S 中最大的数在二进制意义下有 L 位,我们使用一个 [0…L] 的数组 a 来储存线性基。
这种线性基的构造方法保证了一个特殊性质,对于每一个 i , ai 有以下两种可能:
线性基是由空一个个加入的,记线性基为 a , 新加入的为 t 。
逆序枚举 t 的所有二进制位,对于每一个 i :
为保证 a 中只有 ai 的第 i 位为 1 ,只有消去 t 的第 j 位上的 1 ,才可以继续插入。
如果 ai=0 ,则
枚举 j∈[0,i) ,如果 t 的第 j 位为 1 ,则令 t=t⊕ak 。
为保证 a 中只有 ai 的第 i 位为 1 ,只有消去 t 的第 j 位上的 1 ,才可以继续插入。
枚举 j∈(i,L] ,如果 aj 的第 i 位为 1 ,则令 aj=aj⊕t 。
为保证 ak,k∈(j,L] 中第 j 位为 0 .
#include
#include
typedef long long ll;
const int MAXN=55;
int n;
ll LB[MAXN];
ll LBSeq[MAXN];int scnt;
void insert(ll x)
{
int i,j;
for(i=MAXN-1;i>=0;i--)
{
if((x&(1LL<0) continue;
if(LB[i]) x^=LB[i];
else
{
for(j=0;j<=i;j++)
if(x&(1LL<x^=LB[j];
for(j=i+1;jif(LB[j]&(1LL<x;
LB[i]^x;
return;
}
}
}
int main()
{
int i;
scanf("%d",&n);
ll x;
for(i=1;i<=n;i++)
scanf("%d",&x),insert(x);
ll ans=0;
for(i=0;iif(LB[i]) LBSeq[++scnt]=B[i];
for(i=1;i<=scnt;i++) ans^=LBSeq[i];
printf("lld\n",ans);
return 0;
}
#include
#include
typedef long long ll;
const int MAXN=55;
int n,m;
ll LB[MAXN];
ll LBSeq[MAXN];int scnt;
void insert(ll x)
{
int i,j;
for(i=MAXN-1;i>=0;i--)
{
if((x&(1LL<0) continue;
if(LB[i]) x^=LB[i];
else
{
for(j=0;j<=i;j++)
if(x&(1LL<x^=LB[j];
for(j=i+1;jif(LB[j]&(1LL<x;
LB[i]^x;
return;
}
}
}
ll query(ll x)
{
ll res=0;
for(i=1;i<=scnt;i++)
if(x&(1LL<q[i];
return res;
}
int main()
{
int i;
scanf("%d",&n);
ll x;
for(i=1;i<=n;i++)
scanf("%d",&x),insert(x);
ll ans=0;
for(i=0;iif(LB[i]) LBSeq[++scnt]=B[i];
scanf("%d",&m);
while(m--)
{
scanf("%\\d",&x);
if(scnt!=n) --x;
if(x>=(1LL<printf("-1\n");
else printf("lld\n",query(x));
}
return 0;
}