题意:如果nim游戏先手必胜,输出第一步的可行方案数,否则输出0。
我们知道,nim游戏的N-position为所有石子数异或非0,P-position为所有石子数异或得0,因为:
1.终点时所有石子数为0
2.如果当前是N-position,即异或和sum非0,则一定存在一堆石子的数量大于其他堆的异或和(必定存在:考虑sum的最高位1,取这一位为1的任意一堆都可以),将这堆石子拿走一部分使得它的数量等于其他石子的异或和,则sum变为0,转移到P-position
3.如果当前是P-position,从任何一堆石子的取走任意数量,都会这堆石子改变后的数量不等于其他堆的异或和,使sum非0,转移到N-position
因此,我们判断第一步的方案数,只需要找有几堆大于其他堆的异或和,而sum与自身异或就是其他堆的异或和,完事。
#include <iostream>
using namespace std;
const int maxn = 2e6 + 10;
int a[maxn];
int main() {
int n;
while (cin >> n && n) {
int sum = 0, ans = 0;
for (int i = 1; i <= n; i++)
cin >> a[i], sum ^= a[i];
if (!sum) puts("0");
else {
for (int i = 1; i <= n; i++)
if ((sum ^ a[i]) < a[i]) ans++;
printf("%d\n", ans);
}
}
return 0;
}