Description

传统的Nim游戏是这样的:有一些火柴堆,每堆都有若干根火柴(不同堆的火柴数量可以不同)。两个游戏者轮流操作,每次可以选一个火柴堆拿走若干根火柴。可以只拿一根,也可以拿走整堆火柴,但不能同时从超过一堆火柴中拿。拿走最后一根火柴的游戏者胜利。
本题的游戏稍微有些不同:在第一个回合中,第一个游戏者可以直接拿走若干个整堆的火柴。可以一堆都不拿,但不可以全部拿走。第二回合也一样,第二个游戏者也有这样一次机会。从第三个回合(又轮到第一个游戏者)开始,规则和Nim游戏一样。
如果你先拿,怎样才能保证获胜?如果可以获胜的话,还要让第一回合拿的火柴总数尽量小。

Input

第一行为整数k。即火柴堆数。第二行包含k个不超过109的正整数,即各堆的火柴个数。

Output

输出第一回合拿的火柴数目的最小值。如果不能保证取胜,输出-1。

Sample Input

6
5 5 6 6 5 5

Sample Output

21
 
先手要先选一些堆去掉,然后剩下的让对手无论怎么去掉一些,结果XOR值都不为0,这就是先手的必胜策略。
可以知道总是必胜的,因为至少可以拿只剩一堆,使得对方不能拿(不能全部拿走)。
那么让对手无论怎么拿走后的XOR值不为0,就是说我们要求这K个数的极大线性无关组。
而且这题还需要拿走的最少,也就是剩下的尽量大。那么可以从大到小排序,优先拿大的数添加。
这个性质可以用线性基很好的解决。一开始用高斯消元,但是不能解决拿什么数得到极大线性无关组,2k肯定是不行的。
代码如下:
#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[],vec[];
int bin[],zhi,cir;
void gauss(int x)
{
cir=x;
for(int i=;i<=;++i)bin[i]=<<i;
for(int i=bin[];i;i>>=){
//cout<<"h"<<endl;
int j=zhi+;
while(j<=cir&&!(v[j]&i))++j;
if(j>cir)continue;
zhi++;
swap(v[zhi],v[j]);
for(int k=;k<=cir;++k)
if(k!=zhi&&(v[k]&i))
v[k]^=v[zhi];
}
}
int add(int x)
{
for(int i=;~i;--i){
if(x&(<<i)){
if(!v[i]){
v[i]=x;
break;
}
x^=v[i];
}
}
return x>;
}
int main(){
int k;cin>>k;
for(int i=;i<=k;++i){
cin>>vec[i];
}
sort(vec+,vec++k,greater<int>());
ll ans=;
for(int i=;i<=k;++i){
if(!add(vec[i]))
ans+=vec[i];
}
cout<<ans<<endl;
return ;
}

BZOJ3105-新Nim游戏的更多相关文章

  1. BZOJ-3105: 新Nim游戏 (nim博弈&线性基)

    pro: 传统的Nim游戏是这样的:有一些火柴堆,每堆都有若干根火柴(不同堆的火柴数量可以不同).两个游戏者轮流操作,每次可以选一个火柴堆拿走若干根火柴.可以只拿一根,也可以拿走整堆火柴,但不能同时从 ...

  2. BZOJ3105 新Nim游戏 【拟阵】

    题目分析: 我不知道啥是拟阵啊,但有大佬说线性基相关的都是拟阵,所以直接贪心做了. 题目代码: #include<bits/stdc++.h> using namespace std; ; ...

  3. 【BZOJ3105】新Nim游戏(线性基)

    [BZOJ3105]新Nim游戏(线性基) 题面 BZOJ Description 传统的Nim游戏是这样的:有一些火柴堆,每堆都有若干根火柴(不同堆的火柴数量可以不同).两个游戏者轮流操作,每次可以 ...

  4. 【BZOJ3105】[cqoi2013]新Nim游戏 贪心+线性基

    [BZOJ3105][cqoi2013]新Nim游戏 Description 传统的Nim游戏是这样的:有一些火柴堆,每堆都有若干根火柴(不同堆的火柴数量可以不同).两个游戏者轮流操作,每次可以选一个 ...

  5. BZOJ3105: [cqoi2013]新Nim游戏 博弈论+线性基

    一个原来写的题. 既然最后是nim游戏,且玩家是先手,则希望第二回合结束后是一个异或和不为0的局面,这样才能必胜. 所以思考一下我们要在第一回合留下线性基 然后就是求线性基,因为要取走的最少,所以排一 ...

  6. BZOJ3105: [cqoi2013]新Nim游戏

    题解: 线性基?类似于向量上的基底. 此题题解戳这里:http://blog.csdn.net/wyfcyx_forever/article/details/39477673 代码: #include ...

  7. 【bzoj3105】新Nim游戏

    Portal--> bzoj3105 新Nim游戏 Solution 转化一下问题 首先看一下原来的Nim游戏,先手必胜的条件是:每堆数量的异或和不为\(0\) 所以在新的游戏中,如果要保证自己 ...

  8. 【BZOJ-2460&3105】元素&新Nim游戏 动态维护线性基 + 贪心

    3105: [cqoi2013]新Nim游戏 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 839  Solved: 490[Submit][Stat ...

  9. bzoj 3105: [cqoi2013]新Nim游戏 异或高消 && 拟阵

    3105: [cqoi2013]新Nim游戏 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 535  Solved: 317[Submit][Stat ...

  10. 洛谷P4301 [CQOI2013]新Nim游戏

    P4301 [CQOI2013]新Nim游戏 题目描述 传统的Nim游戏是这样的:有一些火柴堆,每堆都有若干根火柴(不同堆的火柴数量可以不同).两个游戏者轮流操作,每次可以选一个火柴堆拿走若干根火柴. ...

随机推荐

  1. Xamarin.Form与Xamarin.Android或Xamarin.IOS的区别简述

    Xamarin.Form与Xamarin.Android或Xamarin.IOS的区别简述: 可能刚刚接触Xamarin的人来说,对于这个概念比较的模糊,认为这说的不都是同一个东西吗?事实并不是这样的 ...

  2. Shiro 整合 SpringBoot

    https://blog.csdn.net/weixin_38132621/article/details/80216056

  3. Centos 7 Ntop 流量分析 安装

    Centos 6 安装 Ntop:https://www.cnblogs.com/weijie0717/p/4886314.html 一.安装 1.添加EPEL 仓库 # yum install ep ...

  4. Docker容器镜像瘦身的三个小窍门(转)

    [转自:http://dockone.io/article/8174] 在构建Docker容器时,我们应尽可能减小镜像的大小.使用共享层的镜像尺寸越小,其传输和部署速度越快. 不过在每个RUN语句都会 ...

  5. 微信小程序记账本进度四

    //index.wxml <view class="container"> <form catchsubmit="formSubmit" &g ...

  6. 2018-2019-2 20165315《网络对抗技术》Exp2 后门原理与实践

    2018-2019-2 20165315<网络对抗技术>Exp2 后门原理与实践 一.实验任务 使用netcat获取主机操作Shell,cron启动 使用socat获取主机操作Shell, ...

  7. Checked Uncheckd异常

    Checked : 你可以在写代码的时候就throw 或者try catch 的 Unchecked :  Error   + RuntimeException .提前无法预测的 http://www ...

  8. Java API使用

    汉化版Java API使用 首次打开出现的问题 在首次打开API时,可能你会遇见这样的问题. 经过查阅,发现是因为文档的权限问题,文档未解锁造成的.这时候只需要给给它权限就可以. 首先关闭程序,单击右 ...

  9. ubuntu 中 vim 的使用

    安装 sudo apt install vim vim  file_name #创建或者打开文件 vim file_name 定位到文件开头 vim file_name + 定位到文件末尾 vim f ...

  10. CentOS开机提示kernel panic - not syncing: Attempted to kill init! 解决方法

    1.重新启动linux 系统,看见如图见面迅速按E键 2.看见如图界面在按E键编辑 3.如图界面使用上下键选择第二个在按E键 4.在最后一行后面添加  enforcing=0 按回车保存退出 5.在此 ...