本文主要是介绍【bzoj 1511】[POI2006]OKR-Periods of Words(kmp+递推),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
1511: [POI2006]OKR-Periods of Words
Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 246 Solved: 140
[ Submit][ Status][ Discuss]
Description
一个串是有限个小写字符的序列,特别的,一个空序列也可以是一个串. 一个串P是串A的前缀, 当且仅当存在串B, 使得 A = PB. 如果 P A 并且 P 不是一个空串,那么我们说 P 是A的一个proper前缀. 定义Q 是A的周期, 当且仅当Q是A的一个proper 前缀并且A是QQ的前缀(不一定要是proper前缀). 比如串 abab 和 ababab 都是串abababa的周期. 串A的最大周期就是它最长的一个周期或者是一个空串(当A没有周期的时候), 比如说, ababab的最大周期是abab. 串abc的最大周期是空串. 给出一个串,求出它所有前缀的最大周期长度之和.
Input
第一行一个整数 k ( 1 k 1 000 000) 表示串的长度. 接下来一行表示给出的串.
Output
输出一个整数表示它所有前缀的最大周期长度之和.
Sample Input
8
babababa
babababa
Sample Output
24
HINT
Source
【题解】【kmp+递推】
【先用kmp求整个字符串的失配函数,然后从前往后枚举每一个有循环节且循环节不是本身的字串,边记录答案边维护前缀和】
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
char s[1000010];
int len,nxt[1000010];
long long f[1000010],ans;
inline void kmp()
{int i,j;nxt[0]=-1;for(i=0;i<len;++i){j=nxt[i];while(j!=-1&&s[i]!=s[j]) j=nxt[j];nxt[i+1]=j+1;}
}
int main()
{int i,j;scanf("%d\n",&len);scanf("%s",s);kmp();for(i=1;i<=len;++i)if(nxt[i]){f[i]=f[nxt[i]]+(long long)(i-nxt[i]);ans+=f[i];}printf("%lld\n",ans);return 0;
}
这篇关于【bzoj 1511】[POI2006]OKR-Periods of Words(kmp+递推)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!