nfls 338. 基本子串字典 题解
nfls 338. 基本子串字典 题解
题目:
基本子串字典 - 题目 - Nanjing Foreign Language School Algorithms Club (nflsoj.com)
首先有一个结论:
对于一个字符串\(s\),所有长度\(\geq|len|/2\)的字符串\(t\)在\(s\)中出现的位置构成等差数列。
这个只需要考虑循环节就可以证明。
对于一个字符串\(s\),考虑它所有border的信息。
假设当前考虑长度在\([2^t,2^{t+1})\)内的所有border。
一定形成这样的形状,假设\(2^t=4\),下图是一个长度为7的border,可以表示成前后两个\(2^t\)的串拼起来:
s: [.......]..........[.......]
(..A.).............(..A.)...
...(..B.).............(..B.)
其中前后长度为\(7\)的串相等的充要条件为:
\(A=A,B=B\)
而\(A,B\)的长度都为\(2^t\),也就是在执行SA的第\(t\)轮,相等的位置,也就是一段区间。
所以我们可以找到\(A\)最后出现的位置和倒数第二次出现的位置(树套树),就可以知道前面的情况(因为是等差数列)。
对于\(B\)同理。
合并两个等差数列可以用exgcd。