题意: 每个前缀出现次数的和.
思路: cnt[pos]记录第pos个前缀x在比他长的前缀y中出现的次数,
递推式:
定义原串的前缀为x类串.
每个长度为a的x类串s会包含2个长度为nxt[a]的x类串t, 而两个相邻的s会有一个重复的t, 所以cnt[a]个s会有cnt[a]+1个t.
最后答案加上每个前缀本身共m. 具体见代码.
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int M = 1e6 + 5;
const int mod = 10007;
int _;
int n;
int m;
char a[M];
char b[M];
int nxt[M];
void getNxt() {
nxt[0] = -1;
int l = -1, r = 0;
while (r <= m - 1) {
if (l == -1 || b[l] == b[r]) {
l++;
r++;
nxt[r] = l;
} else {
l = nxt[l];
}
}
}
int cnt[M];
void init() {
scanf("%d", &_);
while (_--) {
memset(cnt, 0, sizeof(cnt));
int ans = 0;
scanf("%d", &m);
scanf("%s", b);
getNxt();
for (int i = m; i >= 1; i--) {
if (nxt[i] != 0)cnt[nxt[i]] = (cnt[nxt[i]] + cnt[i] + 1) % mod;
}
for (int i = 1; i <= m; i++)ans = (ans + cnt[i]) % mod;
// for (int i = 1; i <= m; i++)debug(cnt[i]);
printf("%d\n", (ans + m) % mod);
}
}
int main() {
init();
return 0;
}