OKR-Periods of Words
题目描述
一个串是有限个小写字符的序列,特别的,一个空序列也可以是一个串. 一个串\(P\)是串\(A\)的前缀, 当且仅当存在串\(B\), 使得\(A = PB\). 如果 \(P!=A\) 并且\(P\)不是一个空串,那么我们说\(P\)是\(A\)的一个\(proper\)前缀. 定义\(Q\) 是\(A\)的周期, 当且仅当\(Q\)是\(A\)的一个\(proper\) 前缀并且\(A\)是\(Q\)的前缀(不一定要是\(proper\)前缀). 比如串 \(abab\) 和 \(ababab\) 都是串\(abababa\)的周期. 串A的最大周期就是它最长的一个周期或者是一个空串(当A没有周期的时候), 比如说,\(ababab\)的最大周期是\(abab\). 串\(abc\)的最大周期是空串. 给出一个串,求出它所有前缀的最大周期长度之和.
输入格式
第一行一个整数\(k(1 < k < 1 000 000)\)表示串的长度. 接下来一行表示给出的串.
输出格式
输出一个整数表示它所有前缀的最大周期长度之和.
样例
样例输入
8
babababa
样例输出
24
code
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+5;
int n;
long long sum,fail[maxn];
char a[maxn];
int main(){
scanf("%d %s ",&n,a+1);
for(int i=2,j=0;i<=n;i++){
while(j&&a[i]!=a[j+1])j=fail[j];
if(a[i]==a[j+1])j++;
fail[i]=j;
}
for(int i=1,j;i<=n;i++){
j=i;
while(fail[j])j=fail[j];
// if(fail[i])fail[i]=j;
sum+=i-j;
}
cout<<sum;
}