题意:给出一个字符串,求所有前缀串出现的总次数。
abab 的前缀串有:a ab aba abab
其中a出现2次
总共出现6次。
思路:先是用KMP求出第i个字符重复的最长前缀的结束位置
dp[i]代表长为i的前缀串(数量1)与其有重复前缀数量。
#include<iostream>
#include<queue>
using namespace std;
const int N = 222222,M = 10007;
int dp[N],next[N];
char s[N];
void get_next(int n)
{
for (int i=2,j=0;i<=n;i++)
{
//cout<<s[j+1]<<s[i]<<endl;
while (j && s[j+1]!=s[i]) j=next[j];
if (s[j+1] == s[i]) j++;
next[i]=j;
}
}
int main()
{
freopen("in","r",stdin);
int t,n;
cin>>t;
while (t--)
{
scanf("%d",&n);
scanf("%s",s+1);
s[0]='#';
get_next(n);
for (int i=1;i<=n;i++) dp[i]=1;
int ans=0;
//for (int i=1;i<=n;i++) cout<<next[i]<<' ';cout<<endl;
for (int i=1;i<=n;i++)
{
dp[i]=dp[next[i]]+1;
ans+=dp[i];
ans%=M;
}
printf("%d\n",ans);
}
}