该问题属于经典的组合博弈论(Combinatorial Game Theory)范畴,具体为Nim游戏的一个变种。

理论核心:Sprague-Grundy定理与Nim和

在标准的Nim游戏中,每一个堆的石子数量对应一个Grundy值(即及其石子数本身)。游戏局面的胜负性由所有堆石子数量的异或和(XOR Sum,记为 )决定:

  • 必败态(P-position):所有堆石子数量的异或和等于 0。无论先手如何操作,后手总能找到策略让异或和保持为 0,直到所有石子被取完(0)。
  • 必胜态(N-position):所有堆石子数量的异或和不等于 0。先手一定存在某种操作,使得操作后的局面异或和变为 0,从而将必败态留给对手。

问题的转化

在这个变种中,小A拥有一次“赛前作弊”的机会(从小B不注意时拿走 个石子,或者不拿),随后小A作为正式游戏的先手进场。

小A获胜的充要条件是:在小A正式开始第一回合(从堆中取任意石子)之前,桌面上石子的状态必须是对小A有利的必胜态(即异或和 )。

因为小A拥有选择权(作弊或不作弊),所以小A获胜的条件转化为:在所有可能的初始局面修改方案中,是否存在至少一种方案,使得修改后的局面异或和不为 0。

算法推导

我们需要分类讨论初始局面的异或和 以及修改能力 的关系。

设初始异或和

情况一:初始异或和

  • 分析:如果原始局面的异或和已经不为 0,根据Nim游戏规则,这本身就是一个必胜态。
  • 策略:小A选择“不拿石子”(即不使用作弊权)。
  • 结果:游戏以 开始,小A作为先手必胜。
  • 结论:直接输出 YES

情况二:初始异或和

  • 分析:如果原始异或和为 0,这对于先手是必败态。小A必须利用“作弊权”来改变局面,使得新的异或和

  • 操作影响: 假设小A选择第 堆石子(数量为 ),并拿走 个。 新的异或和 计算如下: 由于 ,公式简化为:

  • 胜负判定: 小A获胜需要 ,即 。 这等价于 ,即 。 同时,操作必须合法,即被修改的堆必须有足够的石子:

    • 子情况 1 ( 且 存在至少一堆 ): 只要能找到一堆石子数大于等于 ,小A就可以对其进行操作。由于 ,石子数必然发生改变,异或和也必然从 0 变为非 0。小A成功构造出必胜态。 结论:输出 YES

    • 子情况 2 ( 但 所有 ): 小A想改变局面,但没有一堆石子足够让他拿走 个。操作不合法。小A被迫(或只能选择)不操作。 局面保持 。小A先手面临必败态。 结论:输出 NO

    • 子情况 3 (): 无论小A是否“拿走0个”,局面都不会改变,异或和始终为 0。 结论:输出 NO

代码实现

#include <bits/stdc++.h>
using namespace std;
using ll = long long;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n, k;
    cin >> n >> k;
    int S = 0;
    int max_a = 0;

    for (int i = 0; i < n; i++) {
        int a;
        cin >> a;
        S ^= a;
        max_a = max(max_a, a);
    }

    if (S != 0) {
        cout << "YES\n";
        return 0;
    }

    if (k > 0 && max_a >= k) {
        cout << "YES\n";
    } else {
        cout << "NO\n";
    }

    return 0;
}