题解:CF2241F A Bit Odd
Upd 2026.08.30:换了一个更简洁的证明,感谢 PhirainEX 的启发。
显然若剩余序列长度
- 若初始时逆序对数为奇数,则 Alice 可以直接把整个序列扔掉,剩下一个空序列,Alice 必胜。
- 若初始时逆序对数为偶数,且存在一个下标
i 使得s 去掉s_i 后逆序对数为奇数(等价于s_i 贡献的逆序对数为奇数),则 Alice 可以直接把除了s_i 之外的整个序列扔掉,剩下一个长度为1 的序列,Alice 必胜。 - 如果以上两种情况都不满足,我们发挥自己的注意力,猜测此时 Bob 必胜。
:::info[证明]
显然一个逆序对由一个
| 综上,这次操作使序列逆序对数减少的量为奇数,又因为状态三中初始时逆序对数为偶数,Alice 这次操作过后序列的逆序对数变为奇数,Bob 便拿到了状态一,直接把整个序列扔掉就赢了。 |
|---|
由于是
Submission & Code:
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 200005;
int _, n, sum[N], tot;
string s;
bool flag;
signed main() {
cin >> _;
while (_--) {
cin >> n >> s;
s = " " + s;
for (int i = 1; i <= n; i++) sum[i] = sum[i - 1] + (s[i] ^ 48);
tot = 0;
for (int i = 1; i <= n; i++) if (s[i] == '0') tot += sum[i];
if (tot & 1) {
puts("Alice");
continue;
}
flag = 0;
for (int i = 1; i <= n; i++) {
if (s[i] == '0' && (sum[i] & 1)) {
flag = 1;
break;
} else if (s[i] == '1' && ((n - i - sum[n] + sum[i]) & 1)) {
flag = 1;
break;
}
}
puts(flag ? "Alice" : "Bob");
}
return 0;
}