P7475 「C.E.L.U-02」简易输入法

cnblogs

题目传送门

  • 给出 \(n\) 个字符串 \(s_1\sim s_n\)。每个字符串有两个属性,输出次数和字典序。称字符串 \(x\) 小于字符串 \(y\),当且仅当 \(x\) 的输出次数大于 \(y\),或 \(x\) 的输出次数等于 \(y\)\(x\) 的字典序小于 \(y\)

  • \(m\) 次询问,每次给出一个询问串 \(str_i\),求出以 \(str_i\) 为前缀的所有字符串中,第 \(k\) 小的字符串。回答完后,将这个字符串的输出次数 \(+1\)

  • \(n\le 5\times 10^4\)\(m\le 10^5\)\(\sum\limits_{i=1}^m |str_i|\le 5\times 10^5\)\(\color{red}\boldsymbol{\max\limits_{i=1}^n |s_i|\le 10}\)。字符集为英文小写字母集合,即 \(\Sigma=\{\texttt{a},\texttt{b},\dots,\texttt{z}\}\),满足 \(|\Sigma|= 26\)

某个消愁没看见最后一个限制,做法复杂了亿点,我不说是谁。没错,就是我。


【方法一】

先介绍一下不依赖字符串长度限制,时间、空间复杂度稍劣的做法。

看到前缀的问题,考虑对字符串集合建立 Trie 树,假设 \(str_i\) 对应了 Trie 树上根到点 \(u\) 的链,则符合条件的字符串的结束节点 \(v\) 一定在 \(\boldsymbol u\) 的子树中

考虑将子树限制转化为 \(dfn\) 序的限制,记 \(ed_u\) 为以 \(u\) 为根的子树中最大的 \(dfn\) 序,则要求在 \([dfn_u,ed_u]\) 中第 \(k\) 小的值。

使用树状数组套平衡树解决这个问题,支持查询某个区间内小于某个给定值的值个数。先求出第 \(k\) 小值的输出次数,不难发现这个输出次数一定满足,它是最大的一个值,满足输出次数小于它的个数 \(\boldsymbol {<k}\)。二分求出这个值即可。

至于字典序,可以在 dfs 的时候优先遍历字典序小的字母的边,将字典序的大小关系转化成 \(\boldsymbol {dfn}\) 序的大小关系。也可以类似地二分找到第 \(k\) 小值字典序大小。

找出第 \(k\) 小值后,将其从树状数组套平衡树中删除,将其输出次数 \(+1\) 后,再插入回去。

时间复杂度为 \(\mathcal{O}(m\log m\cdot \log (\sum_{i=1}^n|s_i|)\cdot \log n)\),空间复杂度为 \(\mathcal{O}(n\log(\sum_{i=1}^n|s_i|)+(\sum_{i=1}^n|s_i|)\cdot |\Sigma|)\)。实际效率甚至不如某些暴力。

提交记录(TLE 55pts) 代码


【方法二】

我们注意到,【方法一】中拍平成 \(dfn\) 序的目的,就是为了表示某一棵子树的平衡树。那么我们能不能直接在每一个节点处维护以其为根的子树中所有值的平衡树呢?

答案是可以的,注意到 \(\color{red}\boldsymbol{\max\limits_{i=1}^n |s_i|\le 10}\),即一个字符串的结束位置在 Trie 上到根的路径上不超过 \(\boldsymbol{\mathcal{O}(\max_{i=1}^n |s_i|)}\) 个点,说明一个值最多只会在 \(\boldsymbol{\mathcal{O}(\max_{i=1}^n |s_i|)}\) 棵平衡树中出现

这样一来,我们若找到第 \(k\) 小的串在 Trie 中的结束位置,当这个串发生变化时,我们可以暴力修改这个位置及其所有祖先的平衡树

而且,我们根据排名查值的操作变成在一棵完整的平衡树中进行而不是一个序列上,不需要二分出某个排名的值。

找到第 \(k\) 小的字符串后,可以根据它的 \(dfn\) 序确定 Trie 上包含它的所有子树,在这些子树的平衡树中将其删去,将其输出次数 \(+1\) 后,再插入回去。

这么一来,时间复杂度优化至 \(\mathcal{O}((n+m)\log n\cdot (\max_{i=1}^n|s_i|)+(\sum_{i=1}^n|s_i|)\cdot |\Sigma|)\),空间复杂度优化至 \(\mathcal{O}((\sum_{i=1}^n|s_i|)\cdot |\Sigma|+n\cdot (\max_{i=1}^n|s_i|))\)

提交记录(AC 100pts) AC 代码


【方法三】

拍平成 \(dfn\) 序后和 P5356 一样分块,笔者没有实现,读者可以自行尝试。

根号的做法其实挺多,时间、空间复杂度也不太好说,可以参考 P5356 题解区中的各种做法。

posted @ 2023-10-16 22:16  lzyqwq  阅读(28)  评论(0)    收藏  举报