首页 > 代码库 > BZOJ1511: [POI2006]OKR-Periods of Words

BZOJ1511: [POI2006]OKR-Periods of Words

1511: [POI2006]OKR-Periods of Words

Time Limit: 5 Sec  Memory Limit: 64 MB
Submit: 174  Solved: 92
[Submit][Status]

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

Sample Output

24

HINT

Source

题解:

想了一会儿发现最大周期其实就是求前缀的len--最短的前缀==后缀的len

正确性显然,然后就kmp搞定了。

代码:

 1 #include<cstdio> 2  3 #include<cstdlib> 4  5 #include<cmath> 6  7 #include<cstring> 8  9 #include<algorithm>10 11 #include<iostream>12 13 #include<vector>14 15 #include<map>16 17 #include<set>18 19 #include<queue>20 21 #include<string>22 23 #define inf 100000000024 25 #define maxn 1000000+526 27 #define maxm 500+10028 29 #define eps 1e-1030 31 #define ll long long32 33 #define pa pair<int,int>34 35 #define for0(i,n) for(int i=0;i<=(n);i++)36 37 #define for1(i,n) for(int i=1;i<=(n);i++)38 39 #define for2(i,x,y) for(int i=(x);i<=(y);i++)40 41 #define for3(i,x,y) for(int i=(x);i>=(y);i--)42 43 #define mod 100000000744 45 using namespace std;46 47 inline int read()48 49 {50 51     int x=0,f=1;char ch=getchar();52 53     while(ch<0||ch>9){if(ch==-)f=-1;ch=getchar();}54 55     while(ch>=0&&ch<=9){x=10*x+ch-0;ch=getchar();}56 57     return x*f;58 59 }60 int n,next[maxn];61 ll ans;62 char s[maxn];63 64 int main()65 66 {67 68     freopen("input.txt","r",stdin);69 70     freopen("output.txt","w",stdout);71 72     n=read();73     scanf("%s",s+1);74     for(int i=2,j=0;i<=n;i++)75     {76         while(j&&s[j+1]!=s[i])j=next[j];77         if(s[j+1]==s[i])j++;78         next[i]=j;79     }80     for1(i,n)if(next[next[i]]!=0)next[i]=next[next[i]];81     for1(i,n)if(next[i])ans+=(ll)(i-next[i]);82     printf("%lld\n",ans);83 84     return 0;85 86 }
View Code

 

BZOJ1511: [POI2006]OKR-Periods of Words