BZOJ3105 - New Nim Game

Description

The traditional Nim game is like this: there are some piles of matches, each pile has several matches (the number of matches can be different for different piles). Two players take turns to operate, and each time they can choose a match stack to take away several matches. You can take just one or the whole stack, but not from more than one stack at a time. The player who takes the last match wins.
The game for this question is slightly different: in the first turn, the first player can simply take several entire piles of matches. You can take all of them, but not all of them. The same goes for the second round, where the second player has one such opportunity. From the third turn (the first player's turn again), the rules are the same as for Nim games.
How can you guarantee a win if you take it first? If you can win, try to keep the total number of matches in the first round as small as possible.

Input

The first row is an integer k . That is, the number of matches. The second line contains k positive integers up to 10 9 , that is, the number of matches in each pile.

Output

Output the minimum number of matches taken in the first round. If a win is not guaranteed, output -1.

Sample Input

6
5 5 6 6 5 5

Sample Output

21
 
The first mover must first select some piles to remove, and then let the opponent remove some of the remaining ones, and the result is that the XOR value is not 0. This is the winning strategy of the first mover.
You can know that you will always win, because at least you can take a bunch of them, so that the opponent can't take them (can't take them all).
Then let the XOR value of the opponent not be 0 no matter how they take it, that is to say, we require a maximum linearly independent group of K numbers.
And this question also needs to take away the least, that is, the rest is as large as possible. Then you can sort from large to small, and add the largest number first.
This property can be solved well with linear basis. At the beginning, Gaussian elimination was used, but it could not solve what number to get a maximum linearly independent group. 2 k is definitely not acceptable.
code show as below:
#include <iostream>
#include <string.h>
#include <string>
#include <map>
#include <algorithm>
#include <stdio.h>
#include <set>
using namespace std;
typedef long long ll;
int v[233],vec[233];
int bin[233],zhi,cir;
void gauss(int x)
{
    cir=x;
    for(int i=0;i<=30;++i)bin[i]=1<<i;
    for(int i=bin[30];i;i>>=1){
        //cout<<"h"<<endl;
        int j=zhi+1;
        while(j<=cir&&!(v[j]&i))++j;
        if(j>cir)continue;
        zhi ++ ;
        swap(v[zhi],v[j]);
        for(int k=1;k<=cir;++k)
            if(k!=zhi&&(v[k]&i))
                v[k] ^= v[zhi];
    }
}
int add(int x)
{
    for(int i=30;~i;--i){
        if(x&(1<<i)){
            if(!v[i]){
                v[i]=x;
                break;
            }
            x^=v[i];
        }
    }
    return x>0;
}
int  main(){
    int k;cin>>k;
    for(int i=1;i<=k;++i){
        cin>>vec[i];
    }
    sort(vec+1,vec+1+k,greater<int>());
    ll ans=0;
    for(int i=1;i<=k;++i){
        if(!add(vec[i]))
            ans += vec[i];
    }
    cout<<ans<<endl;
    return 0;
}

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325260251&siteId=291194637