容易发现,求出 nxt 数组之后,对于每一个前缀 i i i 在 n x t [ i ] > 0 nxt[i]>0 nxt[i]>0 的情况下找到它下一个匹配,这个前缀的答案就是 i − j i-j i−j。不过需要进行路径压缩。
#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 10;
char s[N];
int nxt[N];
signed main() {
int n;
cin >> n;
scanf ("%s", s + 1);
for (int i = 2, j = 0; i <= n; i ++) {
while (j && s[i] != s[j + 1])
j = nxt[j];
if (s[i] == s[j + 1])
j ++;
nxt[i] = j;
}
long long ans = 0;
for (int i = 2; i <= n; i ++) {
int j = i;
while (nxt[j])
j = nxt[j];
if (nxt[i])
nxt[i] = j;
ans += i - j;
}
cout << ans << '\n';
return 0;
}