#kmp#洛谷 2375 jzoj 3756 loj 2246 codevs 3319 动物园

题目

求字符串 S 的前缀i中

Π 前缀与后缀不重叠的数量 + 1


分析

初级版本 洛谷 3435
所以说其实可以在匹配 f a i l 的时候顺带 a n s [ i ] = a n s [ j ] + 1
然而不重叠的话就特判特判就好了


代码

#include <cstdio>
#include <cstring>
int n,fail[1000001],len,j,answer,ans[1000001]; char s[1000001];
int in(){
    int ans=0; char c=getchar();
    while (c<48||c>57) c=getchar();
    while (c>47&&c<58) ans=ans*10+c-48,c=getchar();
    return ans;
}
void print(int ans){
    if (ans>9) print(ans/10);
    putchar(ans%10+48);
}
int main(){
    n=in();
    while (n--){
        scanf("%s",s+1); len=strlen(s+1); fail[1]=ans[0]=j=0; ans[1]=1;
        for (int i=2;i<=len;i++){//匹配fail
            while (j&&s[i]!=s[j+1]) j=fail[j];
            fail[i]=(j+=(s[i]==s[j+1])); ans[i]=ans[j]+1;
        }
        j=0; answer=1;
        for (int i=2;i<=len;i++){
            while (j&&s[i]!=s[j+1]) j=fail[j];
            j+=(s[i]==s[j+1]); while ((j<<1)>i) j=fail[j];//不重叠的必要是j*2>i
            answer=(long long)answer*(ans[j]+1)%1000000007;
        }
        print(answer); putchar('\n');
    }
    return 0; 
}

猜你喜欢

转载自blog.csdn.net/sugar_free_mint/article/details/81782713
今日推荐