题解P3435 [POI2006]OKR-Periods of Words

· · 个人记录

P3435 [POI2006]OKR-Periods of Words题解

题意:

A 串的前缀 B,使 B 串的前缀 C 复制一次,B 串是这个串的子串,求 C 串的最大值的和

思路:

前置芝士:KMP

首先,前缀的话,说明了 nxt_i != 0

我们知道 nxt 是代表最大值,那么我们就要让他变小,可以通过不断将 nxt 往前面跑,到最接近 0 的时候即可

那么这样的话,是会超时的,我们可以通过记忆化,如果在 i 时,nxt_i 不为 0,我们就可以将其赋值给 nxt_i,避免下次再跑

细节:

## 代码: # CODE ```cpp #include <iostream> #include <cstring> #include <cstdio> #define ll long long const int N = 1e6 + 7; using namespace std; char s[N]; int len; ll ans; int nxt[N]; inline void pre() { int j = 0; for (int i = 2; i <= len; i ++) { while (j && s[j + 1] != s[i]) j = nxt[j]; if (s[j + 1] == s[i]) j ++; nxt[i] = j; } } int main() { cin >> len; scanf("%s", s + 1); pre(); for (int i = 2; i <= len; i ++) { int j = i; while (nxt[j]) j = nxt[j]; if (nxt[i]) nxt[i] = j; ans += i - j; } cout << ans << endl; return 0; } ```