KMPOKR-Periods of Words

Posted osea

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了KMPOKR-Periods of Words相关的知识,希望对你有一定的参考价值。

【KMP】OKR-Periods of Words

题目描述

串是有限个小写字符的序列,特别的,一个空序列也可以是一个串。一个串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的最大周期是空串。
给出一个串,求出它所有前缀的最大周期长度之和。

 

输入

第一行一个整数k,表示串的长度。
接下来一行表示给出的串。

 

输出

输出一个整数表示它所有前缀的最大周期长度之和。

样例输入

8
babababa

样例输出

24

提示

对于全部数据,1<k<1e6


 

【题意】:

看题意,人话吗?我真的看了很久很久,最后还是找博客上的解释才看懂是什么 意思。。。

参考博客:蒟蒻のblog


 

思路

先把题面转成人话:

对于给定串的每个前缀i,求最长的,使这个字符串重复两边能覆盖原前缀i的前缀(就是前缀i的一个前缀),求所有的这些“前缀的前缀”的长度和

利用nextnext的性质:前缀ii的长度为next[i]的前缀和后缀是相等的

这说明:如果有i一个公共前后缀长度为j,那么这个前缀i就有一个周期为i-j

见下图

技术图片

显然图中蓝色线段是黑色线段的一个周期

那么接下来的问题就容易了:

先求出next数组


 

【代码】:

技术图片
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N = 1e6 + 10;
 4 typedef long long ll;
 5 char p[N];
 6 int Next[N],m;
 7 
 8 void get_Hash()
 9     for(int i=2,j=0; i<=m;i++)
10         while( j && p[i] != p[j+1] ) j = Next[j];
11         if( p[i] == p[j+1] ) j++;
12         Next[i] = j ;
13     
14 
15 int main()
16 
17     scanf("%d",&m);
18     scanf("%s",p+1);
19     ll ans = 0 ;
20     get_Hash();
21     for(int i=1;i<=m;i++)
22         int j = i ;
23         while( Next[j] ) j = Next[j];
24         if( Next[i] ) Next[i] = j ;
25         ans = ans + (i-j);
26     
27     printf("%lld\\n",ans);
28     return 0 ;
29 
View Code

 

 

 

以上是关于KMPOKR-Periods of Words的主要内容,如果未能解决你的问题,请参考以下文章

在 Dart 中,List.from 和 .of 以及 Map.from 和 .of 有啥区别?

JavaScript `of` 关键字(for...of 循环)

nth-child,nth-last-child,only-child,nth-of-type,nth-last-of-type,only-of-type,first-of-type,last-of-

be aware of是啥意思

be aware of是啥意思

全文搜索条件 'control of' 中的 'of' 附近的语法错误