【题解】周期长度和
【题解】周期长度和
为什么可以用 KMP 解决这道题
根据 \(\text{proper}\) 前缀及周期的定义可知,
如果 \(A\) 存在周期,那么 \(A\) 一定有公共前后缀,周期为 \(A\) 的长度减去公共前后缀的长度
既然要求最大周期长度,那么就需要令公共前后缀最短
而 \(\operatorname{KMP}\) 预处理出来的 \(\pi\) 数组表示的就是前缀串的最长公共前后缀长度
通过 \(\pi\) 数组不断向前跳,可以找到最短公共前后缀长度(代码实现就是上面跟并查集似的那四行)
这样就可求所有前缀的最大周期长度之和了
#include<bits/stdc++.h>
using namespace std;
const int maxN = (1e6+5);
char S[maxN];
int N;
int pi_[maxN];
inline void pre(){
int j = 0;
for(int i = 2;i<=N;i++){
while(j && S[j+1] != S[i]) j = pi_[j];
if(S[j+1] == S[i]) j++;
pi_[i] = j;
}
}
int find(int x){
if(pi_[x]) return pi_[x] = find(pi_[x]);
return x;
}
int main(){
scanf("%d\n",&N);
scanf("%s",S+1);
pre();
long long ans = 0;
for(int i = 1;i<=N;i++){
ans += 1ll * i - 1ll * find(i);
}
printf("%lld",ans);
return 0;
}
不算总结的总结
涉及到公共前后缀的问题可以考虑KMP算法