本题要求所给字符串的前缀在整个字符串中出现的次数的累加和。KMP算法的运用。
容易联想到KMP算法中的next[]数组,当next[i]>0时可以理解为i前面的next[]个字符组成的字符串对应一个前缀。此外长度为n的字符串有n个前缀。
所以sum等于n加上所有next值大于0的元素的个数。
例如:abab
那么他的前缀有a , ab ,aba , abab。
对应的在原串中的个数为a有2个,ab有2个,aba有1个,abab有1个。
那么总数是6。
思路:对这个字符串求出Next数组,那么对于每个Next[i] = k ,那么我们就知道前缀0 -> k - 1处有一个匹配。那么累加即可。
那么只需根据Next数组匹配成功的个数进行累加即可。Next数组最后一个应为字符串的长度。
/**********************
* author:maple_小贾
* Pro:HDOJ 3336
* algorithm: KMP之next的巧用
* date:2013/11/08
***********************/
#include<cstdio>
#include<cstring>
int next[200000+5];
char s[200000+5];
int test,n;
void GetNext(char *s,int *next){
int i=0,j=-1,m;
next[0]=-1;
m=strlen(s);
while(i<m){
if(j==-1 || s[i]==s[j]){
i++;
j++;
next[i]=j;
}
else{
j=next[j];
}
}
}
int main(){
scanf("%d",&test);
while(test--){
scanf("%d",&n);
scanf("%s",s);
GetNext(s,next);
int sum=n;
for(int i=0;i<=n;i++)
if(next[i]>0)
sum=(sum+1)%10007;
printf("%d\n",sum);
}
}