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;
}
posted @ 2020-07-25 21:09  hyskr  阅读(190)  评论(1编辑  收藏  举报