[BZOJ3105][cqoi2013]新Nim游戏(贪心+高斯消元求线性基)

题目描述

传送门

题解

Nim游戏是所有的xor为0时先手必败
所以就要求第一次拿完之后不含有xor为0的子集(否则对手给子集剩下那个子集那就必败了)
讲每一个数看做一个向量,实际上就是要求一个线性无关组,并且权值最大,然后把不在线性无关组里的第一次拿走
贪心排序了之后高斯消元求解

代码

#include
#include
#include
#include
#include
using namespace std;
#define LL long long
#define N 105

int n,vis[N];
struct hp{LL num,val;}a[N];
LL tot,ans;

int cmp(hp a,hp b)
{
    return a.val>b.val;
}
int main()
{
    scanf("%d",&n);
    for (int i=1;i<=n;++i)
    {
        scanf("%lld",&a[i].num);
        a[i].val=a[i].num;
        tot+=a[i].val;
    }
    ans=tot;
    sort(a+1,a+n+1,cmp);
    for (int i=1;i<=n;++i)
        for (int j=29;j>=0;--j)
            if (a[i].num>>j&1)
            {
                if (!vis[j])
                {
                    vis[j]=i;
                    ans-=a[i].val;
                    break;
                }
                else a[i].num^=a[vis[j]].num;
            }
    if (ans==tot) puts("-1");
    else printf("%lld\n",ans);
}

你可能感兴趣的:(题解,贪心,省选,高斯消元)