卧薪尝胆,厚积薄发。
POI2006 OKR-Periods of Words
Date: Sat Sep 08 00:37:09 CST 2018 In Category: NoCategory

Description:

求串 $S$ 的每个前缀的最大周期长度。
$1\le n \le 10^6$

Solution:

如果是最小周期,那么答案就是 $i-nxt[i]$ ,但是本题要求最大周期,也就是说要找到一个尽量小的串满足前缀等于后缀,但是可以发现如果我们求出了 $1$ ~ $nxt[i]$ 的最小的前缀等于后缀,那么当前串的最小的前缀等于后缀的长度应与之相同,而 $nxt$ 数组第一次不为 $0$ 时求得的最小前缀等于后缀和最大前缀等于后缀长度相同,于是按照这个递推就好了。

Code:


#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
int l;
#define MAXL 1000010
char c[MAXL];
int nxt[MAXL];
int main()
{
scanf("%d",&l);
scanf("%s",c + 1);
nxt[1] = 0;
for(int i = 2,j = 0;i <= l;++i)
{
while(j && c[i] != c[j + 1])j = nxt[j];
if(c[i] == c[j + 1])++j;
nxt[i] = j;
}
for(int i = 2;i <= l;++i)
if(nxt[nxt[i]] != 0)
nxt[i] = nxt[nxt[i]];
long long ans = 0;
for(int i = 1;i <= l;++i)
if(nxt[i])ans += i - nxt[i];
cout << ans << endl;
return 0;
}
In tag: 字符串-KMP
Copyright © 2020 wjh15101051
ღゝ◡╹)ノ♡