HDU3336
本题题意为求字符串的每个前缀在整个字符串中的出现次数。
如果next[j]对答案有一个贡献,那么这个贡献在j中一定会再贡献一次,而且j为结尾的字符串对于总串产生的贡献只有长度为j的子串,(如果这个性质不懂,可以去看我的KMP总结专题性质二)于是我们可以得到转移方程
,最后对所有前缀的贡献取和即为答案。
HDU3336代码
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<stack>
using namespace std ;
const int maxn = 1e6+5;
int Next[maxn];
char str[maxn];
char mo[maxn];
int dp[maxn];
int n1,n2;
void GetNext()
{
int i=0,j=-1;
while(i<n2)
{
if(j==-1||mo[i]==mo[j]) {++i,++j,Next[i]=j;}
else j=Next[j];
}
return ;
}
int kmp()
{
int cnt=0;
int i=0,j=0;
while(i<n1)
{
if(j==-1||str[i]==mo[j]) i++,j++;
else j=Next[j];
if(j==n2)
{
cnt++;
j=0;
}
}
return cnt;
}
int ans[maxn];
int main()
{
int cnt;
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d%s",&n2,mo);
Next[0]=-1;
GetNext();
int ans=0;
dp[0]=0;
for(int i=1;i<=n2;i++)
{
dp[i]=dp[Next[i]]+1;
ans=(ans+dp[i])%10007;
}
printf("%d\n",ans);
}
return 0;
}