题目链接 (Click) (Here)
这个题目其实就是一个(Nim)游戏的简单模型。对于单个的(Nim)游戏(单独一堆的情况),数学归纳可证其(SG)函数值等于其石子个数。所以对于组合起来的整个游戏,其(SG)函数值等于所有子游戏的异或和。如果这个值为(0)那么就是(lose),反之则有必胜策略。
对于必胜策略的要求:在采取必胜策略后,整个游戏的(SG)变为(0)。为此我们先统计最初状态的(SG),然后对于每一堆单独考虑:拆掉堆(i)的游戏为(SG)$w[i]$。要使得游戏$SG$变为$0$,就要异或上一个同样的值,即这一堆的石子要拿到$=SG$(w[i])为为止。
#include <bits/stdc++.h>
using namespace std;
const int N = 500010;
int read () {
int s = 0, ch = getchar ();
while ('9' < ch || ch < '0') {
ch = getchar ();
}
while ('0' <= ch && ch <= '9') {
s = (s << 1) + (s << 3) + ch - '0';
ch = getchar ();
}
return s;
}
int n, w[N], sg;
int main () {
n = read ();
for (int i = 1; i <= n; ++i) {
w[i] = read ();
sg ^= w[i];
}
if (!sg) puts ("lose");
else {
for (int i = 1; i <= n; ++i) {
if (w[i] >= (sg ^ w[i])) {
cout << w[i] - (sg ^ w[i]) << " " << i << endl;
w[i] -= w[i] - (sg ^ w[i]);
for (int i = 1; i <= n; ++i) cout << w[i] << " ";
return 0;
}
}
}
}