题目描述见链接 .
题目转化 为: 对每个前缀串, 求出其 最短公共前缀后缀, 答案即为 总长度 公共长度 .
自然而然地想到 的 数组, 但是 中的 数组 表示的是 最长公共前缀后缀, 考虑怎么转化,
不断执行 , 直到 将要等于 , 这时 就是 最短公共前缀后缀 了 .
#include<bits/stdc++.h>
#define reg register
typedef long long ll;
const int maxn = 1e6 + 5;
int N;
int nxt[maxn];
char S[maxn];
void Get_next(){
nxt[0] = -1;
int i = 0, t = -1;
while(i < N){
if(t == -1 || S[i] == S[t]) nxt[++ i] = ++ t;
else t = nxt[t];
}
}
int main(){
scanf("%d", &N); scanf("%s", S); Get_next();
ll Ans = 0; nxt[0] = 0;
for(reg int i = 1; i <= N; i ++){
if(!nxt[i]) continue ;
while(nxt[nxt[i]]) nxt[i] = nxt[nxt[i]];
if(nxt[i] < i) Ans += i - nxt[i];
}
printf("%lld
", Ans);
return 0;
}