「题解」CF1033G Chip Game(手摸博弈)
神仙博弈!
考虑给定 \(a,b\)。
可以证明,\(\{v_i\}\) 组成的游戏,与 \(\{v_i\bmod (a+b)\}\) 完全等价。
证明不再赘述,可以直观感性地理解。
枚举 \(s=a+b\),将 \(v_i\bmod s\) 后排序。
仍然考虑给定 \(a,b\),如何判断胜负情况。
\(A\) 必胜、\(B\) 必胜的情况本质是一致的,可以简单求解。
接下来考虑如何判断先后手必胜。
先排除掉 \(v_i<a\) 的堆,剩下的堆数记为 \(n\)。
注意到:
- 如果存在 \(a\le v_i<b\),此时 \(\bm A\) 必胜。因为,\(A\) 可以把 \(v_i\) 留在最后操作。
- 如果存在两个及以上 \(i\),\(2a\le v_i<a+b\),此时 \(\bm A\) 必胜。如果 \(A\) 先手,\(A\) 可以选择 \(i\),转化为上面的情况;否则,\(B\) 一定会选择其中一个,\(A\) 接着选另外一个。
排除掉上面的情况,因为这不属于先手或者后手必胜。
此时,若 \(n\) 为偶数,后手必胜,否则先手必胜。
枚举 \(a,b\in (v_{i-1},v_i]\),可以算出 \(a,b\) 的下界:
- 若 \(n\) 为奇数,先手必胜,下界为 \(\dfrac{v_{n-1}}{2}\);否则,后手必胜,下界 \(\dfrac{v_n}{2}\)。
#include <bits/stdc++.h>
using namespace std;
#define int long long
int n, m, v[110], g[110];
signed main() {
cin >> n >> m;
for (int i = 1; i <= n; i++) cin >> v[i];
int fir = 0, sec = 0;
for (int s = 2; s <= 2 * m; s++) {
memcpy(g, v, sizeof g);
for (int i = 1; i <= n; i++) v[i] %= s;
sort(v + 1, v + n + 1);
v[n + 1] = max(v[n], m);
for (int i = 1; i <= n + 1; i++) {
int l = v[i - 1] + 1, r = min(m, v[i]);
if (l > r) continue;
if ((n - i + 1) & 1) l = max(l, v[n - 1] / 2 + 1), fir += max(0ll, min(s - l, r) - max(s - r, l) + 1);
else l = max(l, v[n] / 2 + 1), sec += max(0ll, min(s - l, r) - max(s - r, l) + 1);
}
memcpy(v, g, sizeof v);
}
cout << (m * m - fir - sec) / 2 << " " << (m * m - fir - sec) / 2 << " " << fir << " " << sec << "\n";
return 0;
}

浙公网安备 33010602011771号