Luogu 3435 POI2006OKR-Periods of Words(kmp)

  显然答案应该是Σi-next[next[……next[i]]] (next[next[……next[i]]]>0)。递推即可。

#include<iostream> 
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
int read()
{
    int x=0,f=1;char c=getchar();
    while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
    while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
    return x*f;
}
#define N 1000010
int n,nxt[N],f[N];
long long ans=0;
char s[N];
int main()
{
#ifndef ONLINE_JUDGE
    freopen("a.in","r",stdin);
    freopen("a.out","w",stdout);
    const char LL[]="%I64d\n";
#else
    const char LL[]="%lld\n";
#endif
    n=read();scanf("%s",s+1);
    nxt[0]=-1;
    for (int i=1;i<=n;i++)
    {
        int j=nxt[i-1];
        while (~j&&s[j+1]!=s[i]) j=nxt[j];
        nxt[i]=j+1;f[i]=nxt[i]==0?i:f[nxt[i]];
    }
    for (int i=1;i<=n;i++) ans+=i-f[i];
    cout<<ans;
    return 0;
}

 

posted @ 2018-10-30 13:31  Gloid  阅读(129)  评论(0编辑  收藏  举报