现在我们拥有一个文本串B一个模式串A,询问A在B中出现的次数
很显然这是一个KMP的裸题,但是现在不考虑使用KMP,使用FFT来找A在B中出现的次数
首先定义函数
P(x)=∑i=0m−1(A(i)−B(x−m+i+1))P(x)=\sum_{i=0}^{m-1}(A(i)-B(x-m+i+1))P(x)=i=0∑m−1(A(i)−B(x−m+i+1))
这个函数代表,字符串A在B中匹配以x为最终位置的时候的价值,我们可以看到如果m个字符都匹配上了,那么P(x)=0P(x)=0P(x)=0,因此我们需要快速求出 P(x)P(x)P(x),我们做一下化简
P(x)=∑i=0m−1(A(i)−B(x−m+i+1))2=∑i=0m−1(A2(i)+B2(x−m+i+1)−A(i)∗B(x−m+i+1))=∑i=0m−1A2(i)+∑i=0m−1B2(x−m+i+1)−∑i=0m−1A(i)∗B(x−m+i+1)P(x)=\sum_{i=0}^{m-1}(A(i)-B(x-m+i+1))^2 \\ = \sum_{i=0}^{m-1}(A^2(i)+B^2(x-m+i+1) - A(i) * B(x-m+i+1)) \\ =\sum_{i=0}^{m-1}A^2(i)+\sum_{i=0}^{m-1}B^2(x-m+i+1) - \sum_{i=0}^{m-1}A(i) * B(x-m+i+1) P(x)=i=0∑m−1(A(i)−B(x−m+i+1))2=i=0∑m−1(A2(i)+B2(x−m+i+1)−A(i)∗B(x−m+i+1))=i=0∑m−1A2(i)+i=0∑m−1B2(x−m+i+1)−i=0∑m−1A(i)∗B(x−m+i+1)
前面两项很明显就是前缀和处理即可,但是对于最后的一项,我们要给他转化成卷积的形式,这样才可以方便使用FFT去求解,我们不妨考虑将字符串A逆转,得到字符串S,再将S替换掉公式中的A得到‘
P(x)=∑i=0m−1S2(m−i−1)+∑i=0m−1B2(x−m+i+1)−∑i=0m−1S(m−i−1)∗B(x−m+i+1)P(x)=\sum_{i=0}^{m-1}S^2(m-i-1)+\sum_{i=0}^{m-1}B^2(x-m+i+1) - \sum_{i=0}^{m-1}S(m-i-1) * B(x-m+i+1)P(x)=i=0∑m−1S2(m−i−1)+i=0∑m−1B2(x−m+i+1)−i=0∑m−1S(m