【做题记录】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)\)。代码实现易。

posted @ 2022-01-17 21:14  trsins  阅读(115)  评论(0)    收藏  举报