南外集训 2024.1.5 T3

非常简单的一道题。要好好反思为什么没有做出来。

题意

给定一棵点带权的树,强制在线询问一条链上取恰好 \(m\) 个数按位与的最大值。\(1\le n\le 10^6, 1\le q\le 10^5, 1\le m\le 10, 0\le V< 2^{62}\)

解法

考虑一个暴力:取出树链上所有点权,二分答案 \(x\),则需要检查是否存在至少 \(m\) 个数二进制形式下包含了 \(x\),直接扫描复杂度为 \(\Theta(nq\log V)\)

注意到我们可以在 Trie 树上考虑上述过程:如果右子树至少有 \(m\) 个元素则进入,否则将右子树合并入左子树并进入。注意到后半部分过程可以直接暴力维护,因为我们最多会在整个过程中额外维护 \(m\log V\) 个元素。通过树上可持久化 Trie,我们获得了一个时间 \(\Theta(qm\log^2V)\),空间 \(\Theta(n\log V)\) 的做法,可以获得好多好多分。

进一步思考就会发现,我们实际上只关心这条链上最大的 \(m\log V\) 个数,如果可以获得这些数的集合,问题会变得简单很多。进一步观察发现我们需要做的是:检查是否存在 \(m\) 个数当前位为 \(1\),如果存在那么以后不再考虑这个位为 \(0\) 的数;否则把这些数的当前位全部设成 \(0\)。用一个堆维护所有 \(m\log V\) 个数,每次取出前 \(m\) 大的数即可。总复杂度是 \(\Theta(qm\log V\log(m\log V))\)

下面的问题是树链前 \(k\) 大。假如我们能做 \(\Theta(1)\) 树链最小值,一切都会好起来。长链剖分+倍增即可。

posted @ 2024-01-05 16:48  kyEEcccccc  阅读(62)  评论(0编辑  收藏  举报