【题目链接】
https://www.lydsy.com/JudgeOnline/problem.php?id=3670
http://uoj.ac/problem/5
【题解】
kmp做两遍,第一遍求出next,第二遍与第一遍差不多,在kmp的时候多一个不超过1/2的条件。
时间复杂度
O(N)
O
(
N
)
然而我一开始做的时候没有想到,写了一个瞎搞的暴力,竟然能过现场的全部数据。
【代码】
/* - - - - - - - - - - - - - - -
User : VanishD
problem : [bzoj3670][uoj5][noi2014]
Points : kmp
- - - - - - - - - - - - - - - */
# include <bits/stdc++.h>
# define ll long long
# define inf 0x3f3f3f3f
# define N 1000100
# define P 1000000007
using namespace std;
int read(){
int tmp = 0, fh = 1; char ch = getchar();
while (ch < '0' || ch > '9'){ if (ch == '-') fh = -1; ch = getchar(); }
while (ch >= '0' && ch <= '9'){ tmp = tmp * 10 + ch - '0'; ch = getchar(); }
return tmp * fh;
}
struct Edge{
int data, next;
}e[N];
ll ans;
int nex[N], head[N], place, st[N], top, cnt[N], use[N];
char s[N];
void build(int u, int v){
e[++place].data = v; e[place].next = head[u]; head[u] = place;
}
void dfs(int x, int fa, int p){
st[++top] = x; use[x] = true;
while (x / 2 >= st[p + 1]) p++;
cnt[x] = p;
for (int ed = head[x]; ed != 0; ed = e[ed].next)
if (e[ed].data != fa)
dfs(e[ed].data, x, p);
top--;
}
int main(){
// freopen(".in", "r", stdin);
// freopen(".out", "w", stdout);
for (int opt = read(); opt--;){
scanf("\n%s", s + 1);
int len = strlen(s + 1);
nex[1] = 0;
for (int i = 2; i <= len; i++){
int p = i - 1;
while (p != 0 && s[nex[p] + 1] != s[i])
p = nex[p];
if (p == 0) nex[i] = 0;
else nex[i] = nex[p] + 1;
}
memset(head, 0, sizeof(head));
memset(cnt, 0, sizeof(cnt));
memset(use, 0, sizeof(use));
place = 0;
for (int i = 1; i <= len; i++)
if (nex[i] != 0) build(nex[i], i);
for (int i = 1; i <= len; i++)
if (!use[i]) dfs(i, 0, 0);
ll ans = 1;
for (int i = 1; i <= len; i++)
ans = ans * (cnt[i] + 1) % P;
printf("%lld\n", ans);
}
return 0;
}