题意:给你一个串,问你他的所有前缀和他本身匹配的次数mod10007。
比如 abab 他的子串有a,ab,aba,abab,他们的匹配次数分别是 2,2,1,1,
思路:我们知道nex[i]表示的是你在第i位的时候匹配的最长的相等前后缀的长度(也就是说你在第i位的时候,和你相等的最长相等的前后缀在nex[i]的位置),那么我们就可以定义dp[i]表示的是你在第i位的时候匹配成功的次数,那么
dp[i] = dp[nex[i]] + 1,
解释一下dp方程就是 当你在第i位的时候,和他相等的前缀的匹配次数(dp[nex[i]])加上他这次的匹配(+1)的次数
上代码把:
#include <string.h>
#include <stdio.h>
#include <algorithm>
#include <iostream>
using namespace std;
#define mod 10007
const int maxn = 200000+10;
int nex[maxn],dp[maxn];
char ch[maxn],te[maxn];
void pre_kmp(char str[])
{
memset(nex,0,sizeof(nex));
int len = strlen(str);
int k = -1 , i = 0;
nex[0] = -1;
while(i<len)
{
if(k == -1 || str[i] == str[k])
{
i++,k++;
nex[i] = k;
}
else k = nex[k];
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int ans = 0;
int n;
scanf("%d",&n);
scanf("%s",ch);
memset(dp,0,sizeof(dp));
pre_kmp(ch);
for(int i = 1 ; i <= n ; i++)
{
dp[i] = dp[nex[i]] + 1;
ans += dp[i];
ans%=mod;
}
printf("%d",ans%mod);
puts("");
}
}
/*
1101110010
0100100
*/