分析
首先說明一下題意那個翻譯不太好理解,題目意思是
設原串S
一個字符串的非空真前綴爲Q(proper前綴)不能和S一樣,不能爲空;
如果說S爲Q+Q的前綴,那麼strlen(Q)就是週期;求的是S所有的前綴的最大週期;.
那麼就很容易想到用kmp來做這題,用kmp先對自己進行匹配就是求出所有的含有非空前綴;然後在用i-f[f[i]]求出前綴的最大週期(這個很好證明,可以用最優子結構證明);
代碼
#include<bits/stdc++.h>
#define N 1000005
using namespace std;
long long ans;
int n,f[N];
char p[N];
int main(){
scanf("%d",&n);
scanf("%s",p+1);
int j=0;
for(int i=2;i<=n;i++){
while(j&&p[i]!=p[j+1])j=f[j];
if(p[i]==p[j+1]) j++;
f[i]=j;
}//標註kmp
for(int i=1;i<=n;i++)
if(f[f[i]])f[i]=f[f[i]];//求前綴的最大前綴
for(int i=1;i<=n;i++)
if(f[i])ans+=i-f[i];//計算ans;
printf("%lld",ans);//注意開long long
return 0;
}