题目要求字符串所有前缀在字符串出现的次数之和,次数包括重叠部分(例如ababa,前缀aba出现次数为2次)
朴素思想,枚举前缀,各自KMP算个数,题目数据量较大,不允许这样。
前后缀问题一般会想到利用NEXT数组的性质。
例如abababa,NEXT:0012345,设dp[i]为第i字符为止,前缀(1~i)出现的次数,
dp[i]=dp[nextp[i]]+1代码
#include<iostream>
#include<cstring>
using namespace std;
#define MOD 10007
int nextp[200005],dp[200005];
char s[200005];
void Getnext(int len)
{
int i,j;
i=0,j=-1;
nextp[0]=-1;
while(i<len)
{
if(j==-1 || s[i]==s[j])
{
i++;
j++;
nextp[i]=j;
}
else j=nextp[j];
}
}
int main()
{
int T;
int i,j,k,ans,n;
cin>>T;
while(T--)
{
cin>>n;
cin>>s;
Getnext(n);
ans=0;
memset(dp,0,sizeof(dp));
for(i=1;i<=n;i++)
{
dp[i]=(dp[nextp[i]]+1)%MOD;
ans=(ans+dp[i])%MOD;
}
cout<<ans<<endl;
}
return 0;
}