KMP中的f数组相当于一个状态机。
我们如果能求出处理到第i个字符时,有多少从第1个字符开始的前缀和以i为结尾的后缀完全相同,那么扫一遍这个串然后求和就行了。
从第1个字符开始的前缀和以i为结尾的后缀和f数组意义很像,当沿着失配边一直走(j=f[j]),到0之前,经过多少个节点就是有多少个前缀等于后缀。
所以递推维护每个f[i]到0之间有多少节点。然后扫一遍。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define mod 10007
using namespace std;
char s[200005];
int f[200005];
int c[200005];
int main(){
int T;
scanf("%d",&T);
while(T--){
int len;
scanf("%d%s",&len,s);
c[0]=c[1]=0;
int res=1;
memset(c,0,sizeof(c));
for(int i=1;i<len;i++){
res++;
int j=f[i];
while(j&&s[i]!=s[j]) j=f[j];
if(s[i]==s[j]){
f[i+1]=j+1;
c[i+1]=c[j+1]+1;
res+=c[i+1];
}
else f[i+1]=0;
res%=mod;
}
printf("%d\n",res);
}
return 0;
}
本文详细解释了KMP算法中的f数组概念,如何通过f数组快速匹配字符串,以及提供了一个实现代码示例,包括求解过程和具体应用。
1万+

被折叠的 条评论
为什么被折叠?



