bzoj3105【CQOI2013】新nim游戏

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

sol  :要想必胜则拿完后异或空间不能包含0,即给对手留下一组线性基

   为保证拿走的最小,即留下一组简化前的极大线性基,需从大到小排序,跑线性基即可

   最终答案为自由元的和

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
#define int long long
using namespace std;
int n,top,sum,ans,a[105],b[35],q[105],Pow[35];
bool cmp(int a,int b) { return a>b; }
void gauss()
{
    for(int i=1;i<=n;i++) sum+=a[i];
    for(int i=1;i<=n;i++)
    {
        int tmp=a[i];
        for(int j=30;j>=0;j--)
            if(a[i]&Pow[j])
            {
                if(!b[j]) { b[j]=i; break; }
                else a[i]^=a[b[j]];
            }
        if(a[i]) ans+=tmp;
    }
}
signed main()
{
    Pow[0]=1; for(int i=1;i<=30;i++) Pow[i]=Pow[i-1]<<1;
    scanf("%lld",&n); for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
    sort(a+1,a+n+1,cmp); gauss();
    if(ans) printf("%lld\n",sum-ans);
    else puts("-1"); 
    return 0;
}

 

posted @ 2017-03-13 16:21  Czarina  阅读(178)  评论(0编辑  收藏  举报