BZOJ 1511: [POI2006]OKR-Periods of Words

Description

求一个最长周期.

Sol

KMP.

一个点的最短周期就是 \(i-next[i]\)

此外 \(i-next[next[i]],i-next[next[next[i]]]\) 等等都是它的周期,知道第一个为0的位置.

然后就没有然后了.

Code

/**************************************************************
    Problem: 1511
    User: BeiYu
    Language: C++
    Result: Accepted
    Time:140 ms
    Memory:6172 kb
****************************************************************/
 
#include<cstdio>
#include<iostream>
using namespace std;
 
const int N = 1000005;
 
int n;long long ans;
char s[N];
int f[N];
 
int main(){
    scanf("%d",&n);
    scanf("%s",s+1);
     
    for(int i=2,j=0;i<=n;i++){
        while(j && s[i]!=s[j+1]) j=f[j];
        if(s[i]==s[j+1]) j++;
        f[i]=j;
    }
     
    for(int i=1;i<=n;i++)
        while(f[f[i]]) f[i]=f[f[i]];
     
    for(int i=1;i<=n;i++) if(f[i]) ans=ans+i-f[i];
    cout<<ans<<endl;
    return 0;
}

  

posted @ 2016-10-30 21:12  北北北北屿  阅读(145)  评论(0编辑  收藏  举报