奥赛一本通 1468 OKR-Periods of Words
1468 OKR-Periods of Words
题目大意
如果一个串的某个真前缀复制一次后包含了原来的串,那么将这个真前缀称作原串的一个周期。求出一个串所有前缀的最大周期长度之和。
知识要点
KMP
解题思路
每个循环周期都对应着一个 border,最大周期就对应这最短的 border,利用 KMP 算法持续查找 border 的同时,可以将最短的 border 存储下来进行优化。
参考代码
#include <bits/stdc++.h>
using namespace std;
char s[1000005];
int n, f[1000005];
int main() {
scanf("%d%s", &n, s);
for(int i = 1, j = 0; i < n; i++) {
while(j && s[i] != s[j]) j = f[j - 1];
if(s[i] == s[j]) j++;
f[i] = j;
}
long long ans = 0;
for(int i = 1; i < n; i++) {
int j = f[i];
while(f[j - 1]) j = f[j - 1]; //找最短 border
if(f[i]) f[i] = j, ans += i + 1 - j;
}
printf("%lld\n", ans);
return 0;
}

浙公网安备 33010602011771号