题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=3336
题目要求计算一个字符串的所有前缀字符串在整个字符串中出现的次数。
采用next数组来计算最大前后缀字符串,累加next的值(注意:在累加时,只加下个位置不满足next递归规律的位置的next值)
当k,j位置所对应的字符不同时,k不需要退回初始位置,只需要退回next[k]位置。因为next[k]位置的值目前匹配的最大字符串。
#include <stdio.h>
#include <iostream>
using namespace std;
int nex[200002];
char s[200002];
int n;
void get_next(){
int j=0,k=-1;
nex[0]=-1;
while(j<n){
if(k==-1||s[k]==s[j]){
k++;
j++;
nex[j]=k;
}
else{
k=nex[k];
}
}
}
int main(){
int t,i;
scanf("%d",&t);
while(t--){
int sum=0;
scanf("%d",&n);
scanf("%s",s);
get_next();
for(i=0;i<=n;i++){
if(nex[i]>0&&nex[i]+1!=nex[i+1])
sum+=nex[i];
}
sum+=n;
printf("%d\n",sum%10007);
}
return 0;
}