http://acm.hdu.edu.cn/showproblem.php?pid=3336
题目大意:abab这样的一个字符串,求包括它本身在内的所有子串在原字符串中出现的次数总和是多少。
例如 a出现了两次,ab出现了两次,aba和abab都出现了一次,那么总和就是六次。
思路:
其实就是kmp算法中对于next函数的考察,next函数是该字串的前缀与后缀相等的最大长度。利用这个我们就可以解答;
#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
int next[200005];
char st[200005];
char sa[200005];
void getnext(char const *p)
{
int i,j;
i=0;j=-1;
int len=strlen(p);
next[i]=-1;
while(i<len)
{
if(j==-1||p[i]==p[j])
{
i++;
j++;
next[i]=j;
}
else
j=next[j];
}
}
/*int kmp(char const *s,char const *p)
{
int i,j,n;
i=j=n=0;
int len1=strlen(s);
int len2=strlen(p);
while(i<len1&&j<len2)
{
if(j==-1||s[i]==p[j])
{
i++;
j++;
if(j==len2)
{
j=next[j];
n++;
}
}
else
{
//printf("next= %d %d\n",j,next[j]);
j=next[j];
// printf("i=%d %d\n",i,j);
}
}
return n;
}*/
int main()
{
int t,n,i,j,sum;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
scanf("%s",st);
sum=n;
getnext(st);
for(i=1;i<=n;i++)
{
if(next[i]!=0)
sum=(sum+1)%10007;
}
printf("%d\n",sum);
}
}