KMP
一个串的最小循环节为 i − n x t [ i ] i-nxt[i] i−nxt[i],而如果要求最大循环节就是把 n x t [ i ] nxt[i] nxt[i]跳到刚好不是 0 0 0为止。求出 n x t nxt nxt后我们可以扫一遍把 n x t [ i ] nxt[i] nxt[i]赋成 n x t [ n x t [ i ] ] nxt[nxt[i]] nxt[nxt[i]]。之后 i − n x t [ i ] i-nxt[i] i−nxt[i]算出来的就是最大循环节了。
代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 1000005
using namespace std;
typedef long long LL;
int n,nxt[N]; char s[N]; LL ans=0;
int main(){
scanf("%d%s",&n,s+1);
for (int i=2,nd=0;i<=n;nxt[i++]=nd){
while (nd&&s[nd+1]!=s[i]) nd=nxt[nd];
if (s[nd+1]==s[i]) nd++;
}
for (int i=2;i<=n;i++)
if (nxt[nxt[i]]) nxt[i]=nxt[nxt[i]];
for (int i=2;i<=n;i++)
if (nxt[i]) ans+=i-nxt[i];
return printf("%lld\n",ans),0;
}