【bzoj 3105】: [cqoi2013]新Nim游戏

来源:互联网 发布:藏民对十一世班禅 知乎 编辑:程序博客网 时间:2024/04/30 17:36

http://www.lydsy.com/JudgeOnline/problem.php?id=3105


用拟阵的知识可知,可以贪心


证明来自http://blog.csdn.net/wyfcyx_forever/article/details/39477673

有关拟阵的证明:
我们设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线性无关,显然矛盾。因此交换性存在,证毕。
从而我们可以使用贪心算法确定最优解。


#include <cstdio>#include <cstring>#include <cstdlib>#include <iostream>#include <cmath>#include <algorithm>using namespace std;/************************************************Code By willinglive    Blog:http://willinglive.cf************************************************/#define rep(i,l,r) for(int i=(l),___t=(r);i<=___t;i++)#define per(i,r,l) for(int i=(r),___t=(l);i>=___t;i--)#define MS(arr,x) memset(arr,x,sizeof(arr))#define LL long long#define INE(i,u,e) for(int i=head[u];~i;i=e[i].next)inline const int read(){int r=0,k=1;char c=getchar();for(;c<'0'||c>'9';c=getchar())if(c=='-')k=-1;for(;c>='0'&&c<='9';c=getchar())r=r*10+c-'0';return k*r;}/////////////////////////////////////////////////LL n,a[103],tot,b[33];///////////////////////////////////////////////// /////////////////////////////////////////////////void input(){    rep(i,1,n=read()) tot+=a[i]=read();    sort(&a[1],&a[n+1],greater<LL>());}void solve(){    LL ans=0;    rep(i,1,n)    {        int t=a[i];        per(j,30,0) if(t&(1<<j))        {            if(!b[j])            {                b[j]=t;                break;            }            else t^=b[j];        }        if(t) ans+=a[i];    }    if(ans!=0) cout<<tot-ans<<endl;    else puts("-1");}/////////////////////////////////////////////////int main(){    //freopen("std.in","r",stdin); freopen("std.out","w",stdout);    input(),solve();    return 0;}


0 0
原创粉丝点击