1. 程式人生 > 實用技巧 >OKR-Periods of Words

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;
}