HDU 3336 Count the string(KMP)

来源:互联网 发布:淘宝联盟 百度百科 编辑:程序博客网 时间:2024/06/05 10:41

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 10007using 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;}


0 0
原创粉丝点击