P10218 魔法手杖

感觉考场上做这题还是挺聪明的

答案显然满足二分的性质。考虑枚举答案mid,如果mid满足要求,那么就要满足如下条件:

\[\sum_{a_{i}\oplus x <mid} b^{i}<m \]

\[\forall i,a_{i}+ x >= mid \]

因为如果你这个\(a_{i}\)如果不能满足异或,那么肯定就需要加。
第一个条件即为:被定向加强的水晶在秘术后的魔力值大于等于 mid(对于未被定向加强的水晶,由于 \(a+x=(a\oplus x)+2(a\oplus x)≥(a\oplus x)≥mid\),其也满足该不等式。
第二个式子可以变成\(min\{ a_{i} \}+x>=mid\)将这个作为二分下界即可。然后对于这里,我们要搞的问题就变成了,找到一个x,使第一个式子尽量小。使用01trie,假设当前走到u(顶着走)
先要保证\(x>=mid-min\{ a_{i} \}\)

如果有两个儿子:

1.当前mid这位为1,如果我这位填0,那么左子树肯定都小于了,那么就将左子树的\(sum b_{i}\)加上,那后向右子树递归。如果这位填1,那么右子树肯定都小于,那么就将右子树加上,向左子树递归。所以这个子树的最小答案就是
\(min(sumb[son[u][0]]+dfs(son[u][1]),sumb[son[u][1]]+dfs(son[u][0]))\)
2.当前mid这位为0,如果我这位填0,那么右子树肯定都大于了,那么就向左子树递归。如果这位填1,那么左子树肯定都大于,向右子树递归。所以这个子树的最小答案就是
\(min(dfs(son[u][0]),dfs(son[u][1]))\)

如果只有左/右儿子:

1.当前mid这位为1,肯定要让异或起来更大,所以要相反着填,所以最小答案就是\(dfs(son[u][0/1])\)
1.当前mid这位为零,那么如果相反着填,那么就肯定是大于了,返回0即可。

如果没有儿子了:

根据建树代码可知,这是走到底层的情况,因为是顶着走的,那么就返回0即可。
所以我们就进行二分,然后每次跑一边trie树,这颗trie树应该是不变的。
时间复杂度 \(O(nk^{2})\) 期望得分 72 pts
————————————————————————————————————————————————
考虑如何优化。因为这个在trie上跑一遍是不太可能优化的,那么考虑怎么优化二分。考虑优先让高位为1,那么mid这一位就是1,然后跑一遍dfs,看下\(sumb_{i}\)是否小于m,如果小于,那么答案这位就是1,否则就是0。然后我们又得到了一个 \(O(nk^{2})\)算法 期望得分 72 pts。考虑贪心,贪在子树内,若当前填1是否有解,然后往下填。

\[\sum_{a_{i}\oplus x <mid} b^{i}<m \]

\[\min \{a_{i}\}+ x >= mid \]

如果这位填1,那么考虑先满足条件,还是分四类:

如果有两个儿子:

1.当前mid这位为1,如果我x这位填0,那么左子树肯定都小于了,判断先前花费的b加上sumb[son[u][0]]是否小于等于m,满足了第一个式子。为了尽可能满足第二个式子,那么后面得都是1。这时,判断所有进行加法操作中的最小值加上\(x+((1<<dep)-1)\)是否大于等于\(ans+2^{k}\)。然后向右子树递归。如果我x这位填1,那么右子树肯定都小于了,判断先前花费的b加上sumb[son[u][1]]是否小于等于m,满足了第一个式子。为了尽可能满足第二个式子,那么后面得都是1。这时,判断所有进行加法操作中的最小值加上\(x+((1<<(dep+1)-1)\)是否大于等于\(ans+2^{k}\)。然后向左子树递归。
否则mid这位为0肯定是可以的。无论怎么填,都能满足第一个式子,所以我就不搞加法了,全部异或即可。如果我x这位填0,那么右子树肯定都满足了,向左递归。如果我x这位填1,那么左子树肯定都满足了,向右递归。

如果只有左儿子:

1.当前mid这位为1,如果我x这位填0,那么左子树肯定都小于了,判断先前花费的b加上sumb[son[u][0]]是否小于等于m,满足了第一个式子。为了尽可能满足第二个式子,那么后面得都是1。这时,判断所有进行加法操作中的最小值加上\(x+((1<<dep)-1)\)是否大于等于\(ans+2^{k}\)。因为没有右子树,那么(amin+x后面全赋为1)和全局ans取min。如果我x这位填1。为了尽可能满足第二个式子,那么后面得都是1。这时,判断所有进行加法操作中的最小值加上\(x+((1<<(dep+1)-1)\)是否大于等于\(ans+2^{k}\)。然后向左子树递归。
否则mid这位为0肯定是可以的。全部异或即可。如果我x这位填0,向左递归。如果我x这位填1,那么左子树肯定都满足了,那么(amin+x后面全赋为1)和全局ans取min。

如果只有右儿子:

和左边同理

如果没有儿子了:

已经走到底部了,和全局的ans取max

posted @ 2024-05-01 15:42  wuhupai  阅读(4)  评论(0编辑  收藏  举报