CF587F Duff is Mad
Posted gzezFISHER
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF587F Duff is Mad相关的知识,希望对你有一定的参考价值。
题意
给定 \\(n\\) 个字符串 \\(S_1...n\\).
定义 \\(\\textoccur(t, s)\\) 为 字符串 \\(t\\) 在字符串 \\(s\\) 中的出现次数. 有 \\(q\\) 次询问,每次给出 \\(l\\),\\(r\\) 和 \\(k\\),输出 \\(\\sum\\limits_l\\le i\\le r\\textoccur(s_i, s_k)\\).
\\(n,k,\\sum |s_i|\\le 10^5\\)
题解
我们对所有串建立fail树
令 \\(p_i,j\\) 表示串 \\(s_i\\) 的前 \\(j\\) 个字符在AC自动机上对应点的编号,\\(end_i\\) 表示串 \\(s_i\\) 在AC自动机上对应点的编号
有
其中 \\(\\textisanc(x, y)\\) 表示在fail树上 \\(x\\) 是否为 \\(y\\) 的祖先
看到 \\(\\sum |s_i|\\le 10^5\\) 这条限制,容易想到对于 \\(|s_k|\\) 根号分治
令 \\(M=\\sum |s_i|\\)
- \\(|s_k|<=T\\)
容易得到一种做法,\\(\\forall l\\le i\\le r\\),对所有以 \\(end_i\\) 为根的子树的所有点加1,然后查询所有 \\(p_k,i\\) 点上的值之和
把每个询问差分为成 \\([1, l-1]\\) 和 \\([1, r]\\) 两个区间,然后离线下来按右端点排序,维护区间修改单点查询
树状数组可以做到 \\(\\mathcalO(qT\\log M+n\\log M)\\),当然更快的做法是分块的 \\(\\mathcalO(qT+n\\sqrtM)\\) - \\(|s_k|>T\\)
满足这个条件的 \\(k\\) 数量是 \\(\\mathcalO(\\fracMT)\\) 级别的,因此我们考虑对所有的 \\(k\\) 预处理
考虑另一种做法,把所有 \\(p_k,i\\) 标上1,然后查询 \\(\\forall l\\le i\\le r\\),\\(end_i\\) 子树和之和
预处理时我们对 \\(end_i\\) 的子树和做前缀和,询问的差分即可
\\(\\mathcalO(q+\\fracMT\\times n)\\)
选择一个合适的 \\(T\\),我们视 \\(n\\),\\(M\\) 和 \\(q\\) 为同阶,\\(T\\) 取 \\(\\sqrtM\\) 即可
复杂度可以简单地认为是 \\(\\mathcalO(n\\sqrtM)\\)
以上是关于CF587F Duff is Mad的主要内容,如果未能解决你的问题,请参考以下文章
python 速度测试ping然后发布到Twitter - http://arstechnica.com/business/2016/01/cable-lobby-is-really-mad-ab
xsy 2414CF587CDuff in the Army