#include <bits/stdc++.h>
using namespace std;
const int N=2e5+100;
typedef long long ll;
char S[N],T[N];
int nex[N];
int dp[N];//dp[i]表示截止到第i个位置,出现的前缀字符串的总数
//dp[ nex[i] ] = dp[ nex[i] ] + dp[i]
void get_next(char *S,int length)//求next数组
{
nex[0]=nex[1]=0;
for(int i=2,j=0;i<=length;i++)
{
while(j&&S[i]!=S[j+1])j=nex[j];
if(S[i]==S[j+1])j++;
nex[i]=j;
}
}
int main()
{
int n;
cin>>n;
cin>>T+1;
get_next(T,n);
for(int i=1;i<=n;i++)dp[i]=1;//初始化
for(int i=n;i>=1;i--)
{
dp[nex[i]]+=dp[i];
}
//for(int i=1;i<=n;i++)cout<<dp[i]<<" ";
//cout<<endl;
//对于样例abcabc,dp数组依次为 2 2 2 1 1 1
ll ans=0;//若ans为int型,无法通过最后一个测试点
for(int i=1;i<=n;i++)//枚举每个位置1~n
{
ans+=dp[i];//累加所有的dp[i]
}
//附:本题错误解法
//求出next数组后遍历next数组,若不为0则ans+2,若为0则ans+1
//此种解法可以通过前面19个测试点,但无法通过最后一个测试点
//此解法的bug在于next数组记录的是最长前缀,可能忽略一些被最长前缀包含的前缀
//如对于样例abcabca,next数组为0 0 0 1 2 3 4,此解法得到答案11,但正确答案为12
//错误之处在于,对于前缀a,其出现了3次,但只有nex[4]记录了前缀a出现的次数,只加了2次
//实际上abca同样也包含了a,但是被忽略了
cout<<ans<<endl;
return 0;
}
你也喜欢幸运字符串吗? kmp
最新推荐文章于 2024-07-25 11:27:31 发布