题意:链接
方法:拟阵
解析:
我们是先手操作。
所以我们只需要留下一个局面使得该局面的子局面没有异或和等于零的局面即可。
每一堆火柴数我们看作是一个二进制数的话。
那么我们仅需要拿出一个极大线性无关组则可以达成我们想要的局面。
那么现在设 M=S,L ,S是所有数组成的矩阵,L是我们拿出来的极大线性无关组。
那么现在如果我们证得这个东西有遗传性并且也有交换性的话,那么他就是一个拟阵辣。其实主要就是证交换性的成立。
然后wyf大爷有这么一段证明。
设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线性无关,显然矛盾。因此交换性存在,证毕
向量组的任意两个极大线性无关组等价。
这是线性代数教程上的话,自己去看证明。
所以我们通过拟阵证明了贪心的最优性,接下来我们就只需要贪心求解一个极大线性无关组就可以了。
然后类似高斯消元那样就可以了。
代码:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 110
using namespace std;
typedef long long ll;
int a[N];
int b[N];
int n;
ll sum;
ll ans;
int cmp(int x,int y)
{
return x>y;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%d",&a[i]),sum+=a[i];
sort(a+1,a+n+1,cmp);
for(int i=1;i<=n;i++)
{
int tmp=a[i];
for(int j=30;j>=0;j--)
{
if(a[i]&(1<<j))
if(!b[j]){b[j]=i;break;}
else a[i]^=a[b[j]];
}
if(a[i]!=0)ans+=tmp;
}
if(ans==0)printf("-1\n");
else printf("%lld\n",sum-ans);
}