1 条题解
-
0
题目大意
有一棵 个节点的树,两人轮流移动棋子。移动规则为:从当前节点 移动到相邻且未访问过的节点 ,且必须满足
Eikooc 先手,她可以选择任意起始节点。双方都采取最优策略,无法移动者输。
游戏开始前,Eikooc 可以重新给节点编号(即任意排列 到 的编号),目标是最大化她作为先手时能保证获胜的起始节点数量。
要求输出任意一个能达到该最大值的重标号方案。
关键观察与推导
1. 什么时候 ?
设 是两个正整数。
令 为 和 的最高位(二进制最高位)。- 若 ,则 的第 位为 ,而 的第 位为 ,因此 所以条件 自动成立。
- 若 ,则 的最高位就是 ,这大于或等于 的最高位,因此条件可能不成立,通常不成立。
结论:
相邻两个节点的最高位相同 ⇒ 移动一定合法(条件成立)。
相邻两个节点的最高位不同 ⇒ 移动可能非法(通常非法)。
2. 对游戏胜负的影响
如果某个节点 的所有相邻节点与它的最高位都不同,那么从 出发,对方无法合法移动(因为条件不成立),所以 是必胜点(先手直接赢)。
如果树中所有边连接的两个节点最高位都不同,那么任意节点作为起始点都是必胜点,这是 Eikooc 能得到的最大优势。
3. 如何保证任意相邻节点最高位不同?
这是图的二部着色问题:
把树黑白染色(相邻节点颜色不同)。
如果我们能把所有最高位相同的节点放在同一种颜色里,那么任何边连接的两个节点必然最高位不同。
4. 最高位分组
考虑 到 的所有整数:
- 最高位为 的数有 个(),但最后一组可能不满。
- 这些组互不相交。
设树黑白染色后,白色节点数为 ,黑色节点数为 。
不妨设 (否则交换颜色)。关键:
,所以 。
这意味着 的二进制表示只用到低于 的位。
5. 构造方法
把 到 按最高位分组(大小为 或更少)。
对于每个 ( 到 ):- 如果 的第 位是 ,就把这组的数全部分配给白色节点。
- 否则全部分配给黑色节点。
这样:
- 白色节点总数正好是 (因为二进制分解唯一)。
- 同一组的数(最高位相同)都在同一颜色中。
- 相邻节点颜色不同 ⇒ 最高位不同。
6. 为什么这样是最优的?
如果存在一条边的两个节点最高位相同,那么这两个节点在同色(按最高位分组)且相邻。
考虑这些同色节点构成的连通块(在原树中),它至少有两个节点,因此一定有叶子节点。
从与该叶子相邻的同色节点出发,对方可以走到该叶子,然后当前玩家无法再走(因为叶子相邻节点只有已访问的,且它们的最高位相同导致条件不成立?需要仔细分析)。实际上原题解证明:若存在相邻同最高位,则存在某个起始节点必败,从而不是最大胜率。
因此,最大化必胜起始节点数等价于消除所有相邻同最高位。
算法步骤
- 读入树,建立邻接表。
- 从任意节点(比如 )开始 DFS,进行黑白染色( 或 )。
- 统计白色节点数 ,若 ,则交换颜色(使 为较小者)。
- 把 到 按最高位分组:
- 对每个 从 到 ,
msb = 31 - __builtin_clz(i)(或类似方法)。 - 把 放入
vals[msb]中。
- 对每个 从 到 ,
- 初始化答案数组
ans。 - 对于 到 :
- 如果 的第 位是 ,则把
vals[k]中的数依次分配给白色节点(按顺序取未填的白色节点)。 - 否则分配给黑色节点。
- 如果 的第 位是 ,则把
- 输出
ans(即每个原树节点的新编号)。
复杂度
- 染色:
- 分组:
- 分配:
- 总复杂度:,满足 总和 。
示例验证
例1:
只有 1 个节点,随便标号 。
例2:,边
染色:,。
分组:- :( 个数)
- :( 但只有 在范围内)
二进制 ,第 0 位为 1 ⇒ 第 0 组给白色(节点 1),第 1 位为 0 ⇒ 第 1 组给黑色(节点 2)。
结果:节点 1 标 ,节点 2 标 。输出1 2(或交换黑白可得2 1)。例3:,边
树为星形,中心 1 与 2、3 相邻。
染色:设 ,(白色节点数)。
分组:- :
- :( 到 ,因为 个数,但 所以 最高位都是 1)
二进制 :
第 0 位 1 ⇒ 第 0 组给白色节点(节点 1 标 1)
第 1 位 0 ⇒ 第 1 组给黑色节点(节点 2,3 依次标 2,3)输出
1 2 3。
总结
本题核心是利用二进制最高位分组和树的双色染色,通过巧妙分配编号,使得任意相邻节点的最高位不同,从而让先手任意选点都能获胜。这是基于二进制表示和树结构的经典构造题。
- 1
信息
- ID
- 6234
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 2
- 标签
- 递交数
- 2
- 已通过
- 1
- 上传者