奥赛一本通 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;
}
posted @ 2026-09-24 09:54  萧西待水  阅读(10)  评论(0)    收藏  举报