原题链接

分析

一堆可以变成两堆,对于每堆的一种子情况来说都有:
$$
sg(a,b)\rightarrow sg(a)\ xor\ sg(b)
$$
只需要遍历a,b的所有情况就可以了。

代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <bits/stdc++.h>
using namespace std;
const int N = 101;
int n;
int f[N];

int sg(int x) {
if(f[x] != -1) return f[x];
unordered_set<int> S;
for(int k = x - 1; k >= 0; --k) {
for(int j = x - 1; j >= 0; --j) {
S.insert(sg(k) ^ sg(j));
}
}
for(int i = 0; ; ++i)
if(S.count(i) == 0) {
return f[x] = i;
}
}

int main() {
scanf("%d", &n);
memset(f, -1, sizeof f);
f[0] = 0;
int res = 0;
for(int i = 0; i < n; ++i) {
int a;
scanf("%d", &a);
res ^= sg(a);
}
if(res) printf("Yes");
else printf("No");
return 0;
}