【做题记录】P4965 薇尔莉特的打字机
-
\(\text{P4965}\) 薇尔莉特的打字机
- 算法:trie
题目:
初始有一个仅由大写字母组成的长度为 \(m\) 的字符串 \(S\)。现在有 \(n\) 次操作,每次操作输入字符 \(c\),若 \(c\) 是大写字母则表示在字符串后加入此字符串,否则表示将当前字符串最后一位删除(若字符串为空则不删除)。
对于每次操作都有可能会失效。问最后有多少种可能的字符串。
\(n\le 5\times 10^6\)。
题解:
考虑建出一个 trie,用节点表示字符串。
由于若我当前得到一个字符串 \(T\),那么最终我也必然可以得到 \(T\),即后面的操作全部失效。
将当前可能表示出来的字符串建出来。那么答案就是整棵树。
我们考虑加入一个字符的贡献。
设当前有 \(k\) 个点。
我们设 \(f_{s}\) 表示当前有多少个点的儿子中有 \(s\)。
那么贡献为 \(K=2k-f_s\)。
因为原本就有 \(f_s\) 个节点包含了 \(s\),那么它们再加上 \(s\) 就会算重。
而不考虑这些 \(f_s\) 就是所有节点都新加一个为 \(s\) 的儿子。
考虑转移 \(f\),结论是 \(f_s=k\)。因为现在所有点都有了 \(s\) 这个儿子。
考虑删除。
我们可以看做此时假如所有加入的字母全部失效,那么删除的必将是 \(A\) 中的字母。
我们可以证明若删除的贡献只能在 \(A\) 中删除,不能在后来加入的字母中删除,因为这样没有贡献(会在第一种情况算重)。
所以删除的贡献只为 \(1\)。
具体地,考虑设当前一共有 \(now\) 个删除,那么我们最多会删除到 \(S_{m-now+1}\) 这个点。所以加上的贡献就是 \(S_1\sim S_{m-now+1}\) 的字符串。
然后此时 \(f\) 的转移为 \(f_s++\),因为多的一种即为当前 \(S_{m-now+1}\) 加入 trie 后新得到的儿子 \(s\)。
时间复杂度 \(O(n)\)。代码实现易。

浙公网安备 33010602011771号