题面
Sol
这是一道阅读理解题,读了好久才明白意思。。。
首先可以想到处理出next数组,每次的位置i跳next跳到长度小于i的一半位置,然后继续跳到零统计此时跳的次数就是答案
那么暴力就是\(O(n^2)\)
让我们一起膜拜yyb大佬的倍增跳next
那么优化就是在求next的时候再开一个指针,每次强制跳到i的一半的位置。。。
再开数组cnt,每次由next指针的位置的cnt+1转移而来,然后就没了
# include <bits/stdc++.h>
# define RG register
# define IL inline
# define Fill(a, b) memset(a, b, sizeof(a))
using namespace std;
typedef long long ll;
const int _(1e6 + 1), Zsy(1e9 + 7);
IL ll Read(){
RG ll x = 0, z = 1; RG char c = getchar();
for(; c < '0' || c > '9'; c = getchar()) z = c == '-' ? -1 : 1;
for(; c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) + (c ^ 48);
return x * z;
}
int l, ans, nxt[_], cnt[_];
char s[_];
int main(RG int argc, RG char* argv[]){
for(RG int T = Read(); T; --T){
scanf(" %s", s + 1); cnt[1] = ans = 1; l = strlen(s + 1);
for(RG int i = 2; i <= l; ++i) nxt[i] = cnt[i] = 0;
for(RG int i = 2, j = 0, k = 0; i <= l; ++i){
while(j && s[i] != s[j + 1]) j = nxt[j];
if(s[i] == s[j + 1]) nxt[i] = ++j;
cnt[i] = cnt[j] + 1;
while(k && s[i] != s[k + 1]) k = nxt[k];
if(s[i] == s[k + 1]) ++k;
while((k << 1) > i) k = nxt[k];
ans = 1LL * ans * (cnt[k] + 1) % Zsy;
}
printf("%d\n", ans);
}
return 0;
}