http://acm.hdu.edu.cn/showproblem.php?pid=3336
题目大意讲一个字符串中,每一个子串出现的次数和(如abab,a出现2次,ab出现2次,aba出现1次,abab出现1次,共6次)
KMP算法中next值为不为自身的最大首尾重复子串长度.所以可以建立足够大的数组,在相应next值长度的数组中记录下其出现的次数。最后累加起来就是所求的了。
#include"stdio.h" #include"string.h" char t[200005]; int next[200005],sum1[200005]; void get_next() //计算next值 { int i,j; i=0; j=-1; next[0]=-1; while(t[i]) { if(j==-1||t[i]==t[j]) { ++i; ++j; next[i]=j; } else j=next[j]; } } int main() { int i,n,m,sum2; scanf("%d",&n); while(n--) { for(i=0;i<200005;i++) sum1[i]=0; sum2=0; scanf("%d ",&m); scanf("%s",t); get_next(); for(i=1;i<=m;i++) //因为next值是从-1开始的,所以依次加1 sum1[next[i]]=(sum1[next[i]]+1)%10007; for(i=1;i<=m;i++) //因为next含义为不含本身的最大子串长度,所以要加1,即本身 sum2=(sum2+sum1[i]+1)%10007; printf("%d\n",sum2); } return 0; }