Solution. LG4301 [CQOI2013] 新Nim游戏
Description 展开目录
如果后手必胜,输出
Solution 展开目录
不难发现先手一定存在必胜策略,只需拿的只剩一堆即可,所以
nim 游戏的结论是,先手必败当且仅当石子数的异或和为
考虑用线性基解决这一问题。
假设现在我们有一个线性基,已经被成功插入的数的集合为
那么,我们只需要按照某种顺序将每堆的石子个数插入线性基,无法成功插入的堆就是我们需要拿走的堆。
一个显而易见的贪心是从大到小插入,但这样做的正确性保障呢?
如果插入一个大数
具体的,导致多于一个小数无法插入指的是:
-
如果插入
,则 无法插入线性基。 -
如果不插入
,则 均能够插入线性基。
前者显然是可能发生的,考虑
此时,如果不插入
那么,我们可以得到,插入一个大数,至多会导致一个小数无法插入,于是我们就证明了贪心的正确性。
Code 展开目录
- namespace Main{
- const int N = 105;
- const int L = 30;
- ll k, sum, a[N];
- struct linearBasis{
- int t[L];
- bool insert(int x){
- int save = x;
- for(ri i = L - 1; i >= 0; i--){
- if(!(x >> i & 1)) continue;
- if(!t[i]) return t[i] = x, true;
- else x ^= t[i];
- }
- return false;
- }
- }lb;
- void Main(){
- input(k);
- for(ri i = 0; i < k; i++) input(a[i]);
- sort(a, a + k, greater<int>());
- for(ri i = 0; i < k; i++) if(!lb.insert(a[i])) sum += a[i];
- write(sum);
- return;
- }
- } // namespace
本作品采用 知识共享署名 - 非商业性使用 - 相同方式共享 4.0 国际许可协议 进行许可。