【JZOJ4876】基因突变

Description

给出一个字符串,求有多少个子串与字符串从头开始完全匹配。

Solution

我们发现kmp中的next数据就是来干这个的,于是直接给递推式: fi=fnexti+1 (其中 fi 表示以 i <script type="math/tex" id="MathJax-Element-92">i</script>为结尾有多少个这样的匹配)。

惨痛的教训:
strlen复杂度特别大,所以一开始要存起来。

Code

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#define fo(i,j,k) for(int i=j;i<=k;i++)
#define fd(i,j,k) for(int i=j;i>=k;i--)
#define N 1000200
#define ll long long
using namespace std;
int nx[N];
ll f[N];
char s[N];
int l;
void get()
{
    int j=0;
    fo(i,2,l)
    {
        while(j && s[j+1]!=s[i]) j=nx[j];
        if(s[j+1]==s[i]) j++;
        nx[i]=j;
    }
}
int main()
{
    freopen("gene8.in","r",stdin);
    freopen("gene.out","w",stdout);
    scanf("%s",s+1);
    l=strlen(s+1);
    get();
    ll ans=0;
    fo(i,1,l)
    {
        f[i]=f[nx[i]]+1;
        ans+=f[i];
    }
    cout<<ans;
}
posted @ 2016-11-09 20:20  sadstone  阅读(39)  评论(0编辑  收藏  举报