题解:CF2041I Auto Complete
沉石鱼惊旋
·
·
题解
I. Auto Complete
你需要维护一个搜索引擎。支持 n 次操作。共 4 种操作。
add id str 给搜索引擎插入编号为 id 的内容为 str 的『备选项』。
delete id 删除编号为 id 的『备选项』。
append str 给搜索框后面继续输入 str 的内容。
backspace cnt 给搜索框后面删除 cnt 个字符。
每次操作后,你需要输出目前的『最优』的『备选项』。
『最优』的『备选项』定义为:
- 搜索框内容是这个『备选项』的前缀。
- 若满足 1 的有多个,选最长的。
- 若满足 2 的有多个,选字典序最小的。
- 若满足 3 的有多个,选编号最小的。
保证字符串的字符 ASCII 码范围在 $[33,126]$ 以内。
`add` 操作的 $id$ 两两不同。
`delete` 操作的 $id$ 两两不同。
$id$ 范围在 $[0,n]$ 之间。
---
这个前缀很引导我们往字典树上想。前缀就对应着祖先。
把这些备选项判定拎出来,前缀就对应着必须是祖先,长度对应深度,字典序对应着 DFS 序。
先离线操作,把所有操作全扔到字典树上。删除操作就是跳若干次父亲,所以需要记录字典树每个节点的父亲编号。
这里保证操作合法,所以往下走几步就至多往上走几步,跳父亲暴力跳就行了。
操作离线完就做一次深搜。处理出 DFS 序。
这个编号不是连续的,范围是 $[0,n]$。处理的时候要小心点。
字符集大小很大,直接开数组会浪费很多空间,可以用 map 换空间。
赛时太急了没好好看条件,忘判长度了,最后硬加了一个/xk 写的有点丑。
<https://codeforces.com/contest/2041/submission/293614507>