P10218 魔法手杖
感觉考场上做这题还是挺聪明的
答案显然满足二分的性质。考虑枚举答案mid,如果mid满足要求,那么就要满足如下条件:
因为如果你这个如果不能满足异或,那么肯定就需要加。
第一个条件即为:被定向加强的水晶在秘术后的魔力值大于等于 mid(对于未被定向加强的水晶,由于 ,其也满足该不等式。
第二个式子可以变成将这个作为二分下界即可。然后对于这里,我们要搞的问题就变成了,找到一个x,使第一个式子尽量小。使用01trie,假设当前走到u(顶着走)
先要保证
如果有两个儿子:
1.当前mid这位为1,如果我这位填0,那么左子树肯定都小于了,那么就将左子树的加上,那后向右子树递归。如果这位填1,那么右子树肯定都小于,那么就将右子树加上,向左子树递归。所以这个子树的最小答案就是
2.当前mid这位为0,如果我这位填0,那么右子树肯定都大于了,那么就向左子树递归。如果这位填1,那么左子树肯定都大于,向右子树递归。所以这个子树的最小答案就是
如果只有左/右儿子:
1.当前mid这位为1,肯定要让异或起来更大,所以要相反着填,所以最小答案就是
1.当前mid这位为零,那么如果相反着填,那么就肯定是大于了,返回0即可。
如果没有儿子了:
根据建树代码可知,这是走到底层的情况,因为是顶着走的,那么就返回0即可。
所以我们就进行二分,然后每次跑一边trie树,这颗trie树应该是不变的。
时间复杂度 期望得分 72 pts
————————————————————————————————————————————————
考虑如何优化。因为这个在trie上跑一遍是不太可能优化的,那么考虑怎么优化二分。考虑优先让高位为1,那么mid这一位就是1,然后跑一遍dfs,看下是否小于m,如果小于,那么答案这位就是1,否则就是0。然后我们又得到了一个 算法 期望得分 72 pts。考虑贪心,贪在子树内,若当前填1是否有解,然后往下填。
如果这位填1,那么考虑先满足条件,还是分四类:
如果有两个儿子:
1.当前mid这位为1,如果我x这位填0,那么左子树肯定都小于了,判断先前花费的b加上sumb[son[u][0]]是否小于等于m,满足了第一个式子。为了尽可能满足第二个式子,那么后面得都是1。这时,判断所有进行加法操作中的最小值加上是否大于等于。然后向右子树递归。如果我x这位填1,那么右子树肯定都小于了,判断先前花费的b加上sumb[son[u][1]]是否小于等于m,满足了第一个式子。为了尽可能满足第二个式子,那么后面得都是1。这时,判断所有进行加法操作中的最小值加上是否大于等于。然后向左子树递归。
否则mid这位为0肯定是可以的。无论怎么填,都能满足第一个式子,所以我就不搞加法了,全部异或即可。如果我x这位填0,那么右子树肯定都满足了,向左递归。如果我x这位填1,那么左子树肯定都满足了,向右递归。
如果只有左儿子:
1.当前mid这位为1,如果我x这位填0,那么左子树肯定都小于了,判断先前花费的b加上sumb[son[u][0]]是否小于等于m,满足了第一个式子。为了尽可能满足第二个式子,那么后面得都是1。这时,判断所有进行加法操作中的最小值加上是否大于等于。因为没有右子树,那么(amin+x后面全赋为1)和全局ans取min。如果我x这位填1。为了尽可能满足第二个式子,那么后面得都是1。这时,判断所有进行加法操作中的最小值加上是否大于等于。然后向左子树递归。
否则mid这位为0肯定是可以的。全部异或即可。如果我x这位填0,向左递归。如果我x这位填1,那么左子树肯定都满足了,那么(amin+x后面全赋为1)和全局ans取min。
如果只有右儿子:
和左边同理
如果没有儿子了:
已经走到底部了,和全局的ans取max
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?