1.题目描述:

      栗酱特别喜欢玩石子游戏,就是两个人玩,有n堆石子,每堆有ai个,每次一个人可以轮流选择任意一堆,取走任意多的石子(但不能不取),谁先不能取谁输。
      栗酱觉得这个游戏很有趣,知道有一天,小太阳告诉她,其实如果两个人足够聪明,游戏的结局一开始就已经注定。
      栗酱是一个冰雪聪明的女孩子,她不相信,希望你演示给她看。

2.输入输出:

输入描述:

多组数据,数据第一行T表示数据组数。
每组数据第一行一个n,k表示一共有n堆石子,接下来你试图从第k堆开始取,从第二行开始,每隔一个空格一个第i堆石子的数量ai。
n≤105,  ai≤109

输出描述:

输出“Yes”或“No”代表从该堆开始取是否可以必胜(如果足够聪明)。

示例:

输入:

2        
3 2
1 2 3
2 1
2 1

输出:

No
Yes

3.解题思路:

题目中有说明:

    小太阳哥哥说,如果想赢,就试图把每堆石子数量的异或和变为0,最终便可以获得胜利,不相信自己证一下。
    

因此猜测应该是否能从第k堆中取出一定石子构造异或和为0的情况。我是特判了n=1的情况。

后经过查询资料,该题模型应该为nim游戏。

nim游戏介绍:

正题

   Nim 游戏的规则:有n堆石子,第i堆石子有ai 个,每次可以从某一堆中取走若干个,先后手轮流取,最后无石子可取的人负。

   首先给出结论:将这n堆石子的数量异或起来(即 a1 xor a2 xor ... xor an ),假如不为0,那么先手必胜,否则先手必败。

    由于这东西的证明需要用到二进制,所以下面的证明都在二进制意义下讨论。 

证明
   首先要知道两个定义:

   必胜态:双方足够聪明的情况下,在该状态时拥有操作权者必胜
   必败态:双方足够聪明的情况下,在该状态时拥有操作权者必败
   以及一些基础知识:如果一个状态能转移到任意一个必败态,那么该状态就是必胜态,如果不能,就是必败态。

   在Nim游戏中,异或和不为0就是必胜态,否则是必败态。

   先考虑必胜态怎么必胜:

   假设他们异或起来为 k (k≠0) 且k的最高位为第p位,那么至少存在一个ai,满足 ai的第p位是1,那么我们只需要让ai异或上k即可,由于ai的第p位是1,所以ai异或k肯定是减少了。

	异或完后,所有石子的异或和就变成了0,也就是必败态,由于能转移到必败态,所以一开始的状态为必胜态。

	再考虑必败态为什么必败:

	其实这个就简单很多了……由于此时异或和为0,不管怎么拿,拿完之后肯定不为 0,也就是说,这个状态只能转移到必胜态,那么这个状态就是必败态了。

3.代码:

#include<iostream>
using namespace std;
typedef long long ll;
ll num[100005];
int main(){
    int t;
    cin >> t;
    while( t-- ){
        long long int n,k;
        long long int mid;
        cin >> n >> k;
        for(int i=0 ; i < n; i++ ){
            scanf("%lld",&num[i]);
        }
        mid=num[0];
        for(int i=1;i < n ; i++ ){
            mid=mid^num[i];
        }
        
        mid=mid^num[k-1];
        
        if(n==1)
            cout<<"Yes"<<endl;
        else{
            if(num[k-1]>mid)
                 cout<<"Yes"<<endl;
            else
                 cout<<"No"<<endl;
        }
    }
    return 0;
}