HDU 3336【前缀出现次数】dp+kmp

HDU 3336【前缀出现次数】dp+kmp

  • 题意:求出字符串前缀出现的总次数,答案对1e4+7取模;
  • 思路:我们先考虑kmp匹配前缀与自身,可惜是O(n*n)的复杂度,那么我们该怎样匹配呢?对于这样一个串,在这里插入图片描述
  • 我们可以很容易发现这样一件事cnt[s1]=cnt[s2]=cnt[s3]+1;我们初始化cnt[i]=1;然后从后往前累加cnt[nxt[i]]+=cnt[i],每出现一次长串,就会贡献自身的次数,为什么要倒着扫呢?因为长串对短串才有贡献。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=1e4+7;
char x[200100];
int nt[200100],m,cnt[200100];///cnt[i]代表长度为i的前缀出现次数
void kmp()
{
    
    
    int i,j;
    j=nt[0]=-1;
    i=0;
    while(i<m)
    {
    
    
        while(j!=-1 &&  x[i]!=x[j])
            j=nt[j];
        nt[++i]=++j;
    }
}
int main()
{
    
    
    int t;
    scanf("%d",&t);
    while(t--)
    {
    
    
        cin>>m;
        scanf("%s",x);
        m=strlen(x);
        kmp();
        ll ans=0;
        fill(cnt,cnt+m+1,1);
        for(int i=m; i>=1; i--)
            cnt[nt[i]]+=cnt[i];
        for(int i=1; i<=m; i++)
            (ans+=cnt[i])%=mod;
        printf("%lld\n",ans);
    }

}

猜你喜欢

转载自blog.csdn.net/qq_43653111/article/details/103354633