大致题意:
其中,数据组数<=5, 字符串长度上限为100w
题目还是很简单的,没啥思维难度,适合3年不摸算法竞赛的蛇皮
首先从前到后在构建kmp的next数组的时候,可以对kmp的数组每一个位置k从next[k]递推更新其对应的前缀总数量,也就是这里的num数组同样作用。
但是这里的num要求的只是前缀=后缀,比kmp模板还多了一个要求不重叠。也就是前缀长度不超过当前长度的一半。再搞个跟kmp一样的数组维护一下就好了。我的代码里这个东西叫next1数组。
出于编程规范问题,所以代码全局变量的数组加了个g_前缀,笑死。
垃圾代码如下,仅供参考。
#include<bits/stdc++.h>
using namespace std;
long long mod = 1000000007;
string t;
int g_next[1000010];
int g_next1[1000010];
int g_num[1000010];
void Getnext(string t)
{
long long result = 1;
int j = 0;
int k = -1;
int l = -1;
g_next[0] = -1;
g_next1[0] = -1;
g_num[0] = 0;
while(j < t.length())
{
while (!(k == -1 || t[j] == t[k]))
{
k = g_next[k];
}
j++; k++;
g_next[j] = k;
g_num[j] = g_num[k] + 1;
while (!(l == -1 || t[j - 1] == t[l]) || (l * 2 + 2 > j))
{
//printf("$ %d %d %d\n", l, g_next[l], j);
l = g_next[l];
}
l++;
g_next1[j] = l;
//printf("%d %d %d %d %d\n",j, k, l, g_num[j], g_num[l]);
result = result * (g_num[l] + 1) % mod;
}
printf("%lld\n",result);
}
int main() {
int n;
cin >> n;
while (n--) {
cin >> t;
Getnext(t);
}
}