本来并不打算补这个题, 但是发现想拿到更好的分数, 应该对这题有更多的分析
至于 , 除了让我知道分拆数类型的状态压缩 还可以乱搞, 没有什么意义, 现在也不太可能拥有这个水平
题意
给定一个序列
A and B 每次可以在序列两侧选择并拿出一个数, 把答案异或上它(初始是零)
最终拿完之后, 手上答案更大的赢
A 先手, 输出哪位必胜或平局
不难发现, 由于异或的结合律, 最终 的答案以下记为 异或上 的答以下记为 等于全串异或和
因此如果 全串异或和 , 那么必定没有必胜策略
现在剩下的情况中, 必定没有平局情况
对答案进行二进制拆分, 不难发现对于 的最高位置, 一定有 中的一个拿到这个 , 另外一个拿不到
所以我们可以只考虑最高位, 问题转化成 序列上的问题
暴力做法#
你发现这种两端取数问题长得非常像区间
我们先不考虑 怎么做, 先把所有情况的游戏树列出来
不难发现, 如果 必胜, 那么一定存在一个方法, 使得 每次选择都可以走到一个不管 怎么选都可以必胜的状态
如果 必输, 那么就是无论怎样都传不上去
图片说明

图片中, Alice 必胜, Bob 必输
怎么形象的处理这个问题, 不难发现你不太可能直接把这个大小为 的树建出来, 所以我们可以考虑从 的角度思考
类似区间 , 对这棵树标号

不难发现我们可以预处理出每一个叶子结点的取值 , 每次上提的过程就是 的过程, 发现同编号区间状态一定相同 不难理解, 因为异或的结合律 , 所以直接转移即可做到
分为两种情况:长度为奇数和长度为偶数。
先来看第一种:长度为偶数。我们将 01 序列分为奇数位和偶数位,此时 a_i 的异或和不为 0,所以必然要么是奇数位上有奇数个 1,要么是偶数位上有奇数个 1,于是先手可以直接控制后手所选的 1 的奇偶性,故在此种情况下先手必胜。
再来看长度为奇数的情况:
假如两端都是 0,那么无论先手选哪个都会使当前后手变为长度为偶数的先手状态,于是此时先手必败;
假如一端为 1,那么先手必然要选作为 1 的一端,否则必败,不是最优策略;之后先手需要跟随后手的选择,保证两者的选择完全一致,否则必败我们来简单讨论一下原因:
假如在这一步之前,所有的先手的每一步都跟随着后手选,所以此时先后手选的 1 的数量的奇偶性一定不同,在这一步时,后手选了 1,先手选了 0,那么此时先后手选的 1 的数量的奇偶性变为相同,于是一共选了偶数个 1,还剩奇数个 1,此时一共选了奇数个数字,于是还剩偶数个数字,此时后手作为当前局面的先手进入必胜状态;于是这样选先手必败。
在这一步时,后手选了 0,先手选了 1,与上面的证明同理,可得这样先手必败。
由于先手取走了一个 1,那么此时 1 的个数为偶数,由于每一步先手都跟着后手选,所以先后手必然平分偶数个 1,如果这个个数不能被 4 整除,也就意味着先手被分到了奇数个 1,加上了最初的那个 1,必败。
那么,怎样的序列才能满足先手能跟着后周的每一步选呢?删除掉左右两边相同的数后,剩下的应当满足相邻奇偶位(如 1 和 2 是,但 2 和 3 不是)上的数字相同,这里不证正确性,证法与上面相似。
博弈论应当先考虑基本性质
二进制相关问题往往可以拆成每一位考虑
本题特殊的地方在于因为考虑最值, 只需要考虑最高位即可, 这也是常见的贪心做法
一般来说, 数据模拟应当尽量真实以找到更多的性质
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理