BZOJ3759: Hungergame 博弈论+线性基

学了新的忘了旧的,还活着干什么

题意:一些盒子,每步可选择打开盒子和取出已打开盒子的任意多石子,问先手是否必胜

搬运po姐的题解:

先手必胜的状态为:给出的数字集合存在一个异或和为零的非空子集,则先手必胜

证明:

首先我们有状态A:当前的所有打开的箱子中的石子数异或和为零,且所有关闭的箱子中的石子数的集合中不存在一个异或和为零的非空子集

易证A状态时先手必败

先手有两种操作:

1.从一个打开的箱子中拿走一些石子 那么根据Nim的结论 后手可以同样拿走一些石子使状态恢复为A状态

2.打开一些箱子 由于未打开的箱子中不存在一个异或和为零的非空子集 所以打开后所有打开的箱子中石子数异或和必不为零 于是后手可以拿走一些石子使状态恢复为A状态

故此时先手必败

那么如果初始不存在一个异或和为零的非空子集,那么初始状态满足状态A,先手必败

如果初始存在一个异或和为零的非空子集,那么先手一定可以打开所有的异或和为零的子集,使剩余箱子不存在异或和为零的非空子集,将状态A留给后手,先手必胜

然后就是判断是否有子集异或为0,线性基求一下。

update:其实当n>32时可以直接判断先手胜,因为int范围考虑每一个二进制位一定会有异或为0的

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define N 35
 4 int read(){
 5   int x=0,f=1;char ch=getchar();
 6   while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}
 7   while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();}
 8   return x*f;
 9 }
10 int n,a[N],b[N];
11 bool gauss(){
12   memset(b,0,sizeof(b));
13   for(int i=1;i<=n;i++){
14     for(int j=30;j>=0;j--)
15       if(a[i]>>j&1){
16         if(!b[j]){b[j]=a[i];break;}
17         else a[i]^=b[j];
18       }
19     if(!a[i])return 1;
20   }
21   return 0;
22 }
23 int main(){
24   int T=read();
25   while(T--){
26     n=read();
27     for(int i=1;i<=n;i++)a[i]=read();
28     puts(gauss()?"Yes":"No");
29   }
30   return 0;
31 }

3759: Hungergame

Time Limit: 10 Sec  Memory Limit: 512 MB
Submit: 182  Solved: 131
[Submit][Status][Discuss]

Description

由于施惠国的统治极其残暴,每年从13个区中每个区中选出2名“贡品”参加饥饿游戏,而参加游戏的人必须在险恶的自然环境中杀死其余的人才能存活。游戏只会有一个人活下来 凯特尼斯•伊夫狄恩和同区的皮塔•麦拉克在历经千难万阻后活了下来,然而残忍的游戏只允许一人存活,正当两人准备同时吃下有毒的果实自杀的时候,统治者被打动了,他说:你们两个人跟我玩一个游戏,你赢了,我就让你们两个都活下来。女主角凯特尼斯•伊夫狄恩接受了挑战。

这个游戏是这样的,有n(n<=20)个箱子,每个箱子里面有ai(ai<=1000000000)个石头(怎么放进去的我就不知道了),两个人轮流进行操作(女主角先手),每一次操作可以将任意个(大于0个)未打开的箱子打开(一开始所有的箱子都是关闭的),或者在已经打开的一个箱子里拿走任意个(大于0个)石头(不能超过这个箱子现有的石头数)。最后谁无法操作谁就输了。

现在给出n,和这n个箱子里的石头数ai,女主角想知道她是否有绝对的把握取得胜利(很明显她的对手“统治者”是绝顶聪明的)。

Input

第一行有一个正整数T(表示有T组测试数据),对于每组测试数据有两行,第一行为一个正整数n,接下来有 n个数,第 i 个数表示ai.

Output

有T行:对于每一个测试数据,如果先手可以必胜则输出“Yes”,否则输出“No”(没有引号)。

Sample Input

5
5
18 11 16 19 15
5
18 12 17 10 18
5
17 7 1 10 1
5
19 5 16 19 8
5
18 18 7 4 9

Sample Output

No
Yes
Yes
Yes
Yes

HINT

100%的数据:n<=20,T<=10,ai不超过1,000,000,000;

时间: 2024-10-24 23:14:00

BZOJ3759: Hungergame 博弈论+线性基的相关文章

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

一个原来写的题. 既然最后是nim游戏,且玩家是先手,则希望第二回合结束后是一个异或和不为0的局面,这样才能必胜. 所以思考一下我们要在第一回合留下线性基 然后就是求线性基,因为要取走的最少,所以排一下序,从大到小求. 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<queue> 5 #include<cmath> 6 #include<algor

[CQOI2013]新Nim游戏(博弈论,线性基)

[CQOI2013]新Nim游戏 题目描述 传统的Nim游戏是这样的:有一些火柴堆,每堆都有若干根火柴(不同堆的火柴数量可以不同).两个游戏者轮流操作,每次可以选一个火柴堆拿走若干根火柴.可以只拿一根,也可以拿走整堆火柴,但不能同时从超过一堆火柴中拿.拿走最后一根火柴的游戏者胜利. 本题的游戏稍微有些不同:在第一个回合中,第一个游戏者可以直接拿走若干个整堆的火柴.可以一堆都不拿,但不可以全部拿走.第二回合也一样,第二个游戏者也有这样一次机会.从第三个回合(又轮到第一个游戏者)开始,规则和Nim游

Xor HYSBZ - 2115 (线性基)

Xor HYSBZ - 2115 题意:给一个树,求1到n的最长路径.这里的路径定义为异或和. 线性基~~ 1 #include <bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 struct LiBase{ 5 ll a[63]; 6 //初始化 7 void init(){ 8 memset(a,0,sizeof(a)); 9 } 10 //插入 11 bool insert_(ll x){ 12 for(int

线性基小节

1.线性基的异或集合中每个元素的异或方案唯一. 2.线性基二进制最高位互不相同. 3.线性基中元素互相异或,异或集合不变. 摘自百度文库 线性基能相互异或得到原集合的所有相互异或得到的值. 线性基是满足性质1的最小的集合 线性基没有异或和为0的子集. 证明: 反证法:设线性基S={a1,a2...,an}: 若有子集a1^a2^...^at=0,则a1=a2^a3^...^at,则舍弃a1后一定能通过剩余的元素异或出所有需要a1参与异或的值.设Y=a1^X,因为{a1,a2,...,an}是一组

[BeiJing2011]元素[贪心+线性基]

2460: [BeiJing2011]元素 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 1245  Solved: 652[Submit][Status][Discuss] Description 相传,在远古时期,位于西方大陆的 Magic Land 上,人们已经掌握了用魔法矿石炼制法杖的技术.那时人们就认识到,一个法杖的法力取决于使用的矿石.一般地,矿石越多则法力越强,但物极必反:有时,人们为了获取更强的法力而使用了很多矿石,却在炼制过程中

BZOJ 3105: [cqoi2013]新Nim游戏 [高斯消元XOR 线性基]

以后我也要用传送门! 题意:一些数,选择一个权值最大的异或和不为0的集合 终于有点明白线性基是什么了...等会再整理 求一个权值最大的线性无关子集 线性无关子集满足拟阵的性质,贪心选择权值最大的,用高斯消元判断是否和已选择的线性相关 每一位记录pivot[i]为i用到的行 枚举要加入的数字的每一个二进制为1的位,如果有pivot[i]那么就异或一下(消元),否则pivot[i]=这个数并退出 如果最后异或成0了就说明线性相关... #include <iostream> #include &l

【BZOJ2844】albus就是要第一个出场 线性基 高斯消元

#include <stdio.h> int main() { puts("转载请注明出处[vmurder]谢谢"); puts("网址:blog.csdn.net/vmurder/article/details/43456773"); } 题意:需要注意的是空集(0)是天生被包括的,我为了这个WA了好久~拍了好久,醉了好久~ 题解: 首先有一个我并不知道是为什么(甚至不知道它对不对)的性质: 每一种权值会出现2的自由元(n-线性基个数)次方 次. 感性

[bzoj 2460]线性基+贪心

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2460 网上很多题目都没说这个题目的证明,只说了贪心策略,我比较愚钝,在大神眼里的显然的策略还是想证明一下才安心--所以这里记录一下证明过程. 贪心策略:按魔力值从大到小排序,从大往小往线性基里插,如果成功插入新元素,就选这个,如果插不进去,就不选这个. 证明: 设有n个材料,每个材料的属性值是x[1],x[2],...,x[n],魔力值是v[1],v[2],...,v[n],这里假设v已

BZOJ 2460 元素(贪心+线性基)

显然线性基可以满足题目中给出的条件.关键是如何使得魔力最大. 贪心策略是按魔力排序,将编号依次加入线性基,一个数如果和之前的一些数异或和为0就跳过他. 因为如果要把这个数放进去,那就要把之前的某个数拿出来,而这样交换之后集合能异或出的数是不会变的,和却变小了. # include <cstdio> # include <cstring> # include <cstdlib> # include <iostream> # include <vector