对于给定串的每个前缀i,求最长的,使

这个字符串重复两边能覆盖原前缀i的前缀(就是前缀i的一个前缀),求所有的这些“前缀的前缀”的长度和

 

一张图秒懂

 

 

 

求next[] , 对于前缀i ,设 j =next[i] , 他有一个周期 i- j

#include <bits/stdc++.h>
using namespace std; 
 const int N =1e6+3;
char a[N] ;
#define int long long
  int p[N],n;
 void init(){
 	int i,j=0;
 	
 	for(i=2;i<=n;i++){
 	   while(j>0&&a[i]!=a[j+1]) j=p[j];
 	   
	   if(a[i]==a[j+1]) j++;
	  p[i]=j;	
	}
 }
 signed main(){
 	cin>>n;
 	cin>>a+1; init();
	int i,j;
	
	int ans=0;
	for(i=1;i<=n;i++){
		for(j=i;p[j]!=0;) j=p[j];
		if(p[i]!=0) p[i]=j;
		
		ans+=i-j;
	}
	cout<<ans<<endl;
 }

 

posted on 2023-03-08 14:55  towboat  阅读(26)  评论(0)    收藏  举报