[BZOJ3759] Hungergame
转载自joyouth
首先我们不难看出如果存在一个异或和为
证明如下:
- 首先如果至少存在一个异或和为
的子集,那么一定存在一个异或和为0 的子集使得选取之后剩下的数的任意子集异或和不为0 0 - 假设我们已经选取了一个异或和为
的子集,无论后手怎么做,我们总是有办法使得当前选取的子集异或和为0 ,因为后手无论是拿石子还是取石子之后,当前子集异或和不等于0 ,根据 Nim 游戏可知,此时先手一定有方案使得异或和为0 0
至此,我们证明了如果至少存在一个异或和为
那么题目就转化为求是否存在一个子集异或和为
Description
由于施惠国的统治极其残暴,每年从
这个游戏是这样的,有
现在给出
Input
第一行有一个正整数
Output
有 T
行:对于每一个测试数据,如果先手可以必胜则输出 “Yes”,否则输出 “No”(没有引号)。
Sample Input
5518 11 16 19 15518 12 17 10 18517 7 1 10 1519 5 16 19 8518 18 7 4 9
Sample Output
NoYesYesYesYes
HINT
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;int pos[35];inline bool Insert(int x){ int i; for(i=31;i>=0;--i) { if((x>>i)&1) { if(!pos[i]){pos[i]=x;break;} else x^=pos[i]; } } if(x)return false; else return true;}int main(void){ int i,T,n,x,ans; scanf("%d",&T); while(T--) { memset(pos,0,sizeof(pos)); scanf("%d",&n);ans=0; for(i=1;i<=n;++i) { scanf("%d",&x); ans+=Insert(x); } if(ans)printf("Yes\n"); else printf("No\n"); } return 0;}