连接字符串 题解
连接字符串 题解
题面描述
你有两个小写字母串 \(S\) 和 \(T\) 。令 \(f(S)\) 表示 \(S\) 中所有不同的非空子串形成的集合。
令 \(G\) 表示所有 \(s\in f(S),t\in f(T)\) ,\(s+t\) 形成的多重集。问 \(G\) 中字典序第 \(k\) 小串。
\(|S|,|T|\le 75000\)
题解
字符串字典序考虑逐位枚举确定。
建出 \(S,T\) 的后缀自动机,记从 \(u\) 开始的路径数为 \(cnt_u\)。
若现在已经找到了 \(ans\) 的一个前缀 \(pre\),现在要确定这个以 \(pre\) 为前缀的 \(G\) 中元素个数,设在 \(samS\) 上匹配 \(pre\) 的最长前缀走到节点 \(u\),\(samT\) 上匹配 \(pre\) 的最长后缀走到节点 \(v\),分为两种情况:
- 
\(pre\) 是 \(S\) 的子串,那么有 \(cnt_u\times |samT|\) 的方案 
- 
\(pre\) 由 \(S\) 的字串与 \(T\) 的子串拼接,设 \(s\) 是匹配的最长前缀,\(t\in f(T)\land t\) 是 \(pre\) 后缀,那么只要 \(|t|+|s|\ge |pre|\) 的 \(t\) 就是合法的,设 \(w\) 是第一个包含不合法 \(t\) 的 \(v\) 的祖先那么能算进答案的就是 \(w\) 代表串的后缀到 \(v\) 代表串的前缀。 
只要我们能不断维护 \(u,v,w\) 就可以算出次数。
具体方法:
- 
预处理出 \(trans[u][c]\) 表示从 \(u\) 节点时又来一个 \(c\) 时转移到的位置,类似AC自动机。 
- 
\(u\) 只走 \(trie[u][c]\) 走不动就不走,\(v,w\) 都走 \(trans[u][c]\) 且若 \(w\) 代表的节点太长要向上跳 \(fail\)。 
- 
可以发现 \(v,w\) 是单独更新的,如果通过 \(v\) 用倍增算 \(w\),会有 $\log $ 的复杂度。 
最终复杂度 \(\mathcal O(n|\Sigma|)\),处理一个节点代表的串的前后缀时有一堆细节。

 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号