Description
Input
Output
Sample Input
5 5 6 6 5 5
Sample Output
HINT
k<=100
可知异或和为0则必败,也就是说开头取掉几堆后,剩余集合不能出现异或为0的子集
可知就是维护一个权值和最大的线性无关组(线性基)
从大到小排序,一个个加入线性基
如果没有成功插入,那么说明该元素与其他线性相关,即可以用线性基中的子集异或和表示
这和元素的贪心很像
给出拟阵证明
我们设n个火柴堆的数目为集合S,若某个S的子集r不存在任何一个非空子集异或和0,则r∈I.下面我们证明二元组M=(S,I)是一个拟阵。
遗传性:设A∈I,则A是S的线性无关组,则A的任意非空子集均线性无关,即对A的任意子集B,B均线性无关,因此B∈I,证毕。
交换性:设A,B∈I,且|A|<|B|,我们要证明存在x∈B,使得A∪{x}∈I.利用反证法,假设对于任意x∈B-A,均有A∪{x}不属于I,则B-A中的元素均在A的异或空间中,可由A的子集异或和表示。
因此B中的元素都在A的异或空间中。那么必然有B的异或空间包含于A的异或空间。由|A|<|B|且A,B线性无关,显然矛盾。因此交换性存在,证毕。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 using namespace std; 7 typedef long long lol; 8 int P[40],a[101],n; 9 lol ans; 10 int add(int x) 11 {int i; 12 for (i=30;i>=0;i--) 13 if (x&(1<<i)) 14 { 15 if (P[i]==0) 16 { 17 P[i]=x; 18 break; 19 } 20 x^=P[i]; 21 } 22 return x; 23 } 24 int main() 25 {int i; 26 cin>>n; 27 for (i=1;i<=n;i++) 28 scanf("%d",&a[i]); 29 sort(a+1,a+n+1); 30 for (i=n;i>=1;i--) 31 { 32 if (add(a[i])==0) ans+=a[i]; 33 } 34 cout<<ans; 35 }