您的位置:首页 > 其它

[模板]线性基

2017-07-22 09:50 92 查看

模板第四弹

难度较大,请勿弃疗

给定n个整数(数字可能重复),求在这些数中选取任意个,使得他们的异或和最大。
n<=50


Sample Input
3
3 2 1
Sample Output
3


看上去莫名其妙地想贪心。。。

给些定义:

S为无符号整数集

即S∈N∗

异或和

记为Xor−Sum(S)

Xor−Sum(S)=S1⊕S2⊕....⊕S|S|

张成

记为span(S)

对于所有T∈S,有Xor−Sum(T)∈span(S)

就是所有子集异或和的集合

前方高能!!!

线性相关

S若有元素Sj,使S去掉Sj后的集合S′满足

Sj∈span(S′)

则称S线性相关,否则称S线性无关

前方高能!!!*2+重点!!!

线性基

若B为S的线性基

B满足

1. B∈S,S∈span(B)

2. B线性无关

线性基的长度为|B|

前方高能!!!*3+重点!!!*2

构造与性质

我们设Smax为S中最大的元素

设Len=log2(Smax)

我们可用一个数组g[Len]的数组存储线性基

对于每个i,gi只有两种可能:

1. gi=0

所有j使i<j,gj第i位∈{0,1}

2. gi≠0

所有j使j≠i gj第i位=0

所有j使i<j gi第j位=0

所有j使i>j gi第j位∈{0,1}

假设插入数位x

流程参考代码

void insert(ll x)
{
fd(i,len-1,0)
if(x&(1ll<<i))
if(g[i])
x^=g[i];
else
{
fr(j,0,i-1)
if(x&(1ll<<j))
x^=g[j];
fr(j,i+1,len-1)
if(g[j]&(1ll<<i))
g[j]^=x;
g[i]=x;
return ;
}
}


开始的问题

看了代码,你也许会大呼简单

前面当然要加上插入啊

ll ans=0;
fr(i,0,len-1)
ans^=g[i];
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: