加载中...

ABC 425 FG

F

正着想很难想,逆向思考就会容易许多。

原问题等价于对给定的 \(s\),每次删除任意位置的字符,最后得到空串,删除过程中得到不同的 \(n + 1\) 个序列串的方案数。

问题在于,删除不同位置的字符,可能会得到相同的字符串。而这种情况只会在相邻字符相同时会发生,因此我们只需要钦定对于连续且字符相同的子段,只能删除最左侧的字符,做 \(dp\) 转移时也只需要注意这一个限制条件即可,总复杂度 \(O(n2^{n})\)

code

G

不怎么难的一道 abc \(G\),赛后自己独立补出来了。

\(x\) 异或 \(a\) 数组中某个数 的最小值,可以用 \(01 trie\) 来解决。问题是 \(x \in [0,m-1]\),而 \(m\)\(1e9\) 级别,直接暴力复杂度是 \(O(mlogA)\) 的。

考虑分治:设计函数 \(dfs(p, r)\),表示现在位于字典树中编号为 \(p\) 的结点,求区间 \([0, r]\) 的答案。将当前区间按照最高位拆成两个子区间(一个最高位均为0,另一个均为1),根据结点 \(p\) 下方的 \(0\) 边与 \(1\) 边是否存在,贪心地使最高位为 \(0\);若不能为 \(0\),则只能走最高位设置为 \(1\) 的路线,按上述方式递归即可。但这样仍然会超时,因为当有很多结点同时存在 \(0\) 边 和 \(1\) 边时会同时往两边搜,使得搜索是指数级别的。但我们发现:每次拆分的左子区间的形式始终都是 \([0, 2^{x} - 1]\),且 \(x\) 只与当前搜索的字典树结点的深度有关。因此我们可以预处理这个部分,由于只需要对每个结点求一个值,可以用记忆化搜索使预处理复杂度为 \(O(nlogA)\) 。这样,我们在做最终搜索时就可以避免同时搜两个分支,只需要 \(O(logA)\) 的复杂度就能完成一次搜索(个人觉得这题可以升级为 \(q\) 个查询,总复杂度是 \(O(nlogA + qlogA)\))。具体细节见代码。

code

posted @ 2025-09-28 12:58  jxs123  阅读(22)  评论(0)    收藏  举报