J - Count the string HDU - 3336
题意:让我们求的是字符串的前缀的匹配数的和。
分析:让我们想一想next数组存的是什么,前缀和后缀相同的长度。
举例说明关键步骤也就是那个累加的情况。
abab next数组值为0 0 1 2 即 ab 匹配 而我们要求的是所有前缀的匹配个数,接下来用到的是一个dp数组来加上前面的数目,next[i] = 0是匹配数为 1而next[i] > 0时说明他可以被匹配多次,后面的那个a匹配了 a 和aba 后面那个b匹配了ab和abab即 dp[i] = dp[next[i]]+ 1;
#include <iostream>
#include <cstdio>
#include <stack>
#include <cmath>
#include <set>
#include <cstring>
#include <algorithm>
using namespace std;
#define ll long long
const int maxn = 1000010;
const int mod = 10007;
int next1[maxn], n, m, t, dp[maxn];
char x[maxn], y[maxn];
void kmp_pre(int m)
{
int i, j;
j = -1;next1[0] = -1;
i = 0;
while(i < m){
while(-1 != j && x[i] != x[j]) j = next1[j];
next1[++i] = ++j;
}
}
int main()
{
scanf("%d", &t);
while(t--)
{
scanf("%d", &n);
scanf("%s", &x);
kmp_pre(n);
int res = 0;
for(int i = 1; i <= n; i++)
{
dp[i] = (dp[next1[i]] + 1) % mod;
res = (res + dp[i]) % mod;
}
printf("%d\n", res);
}
}