/*
cnt代表匹配到的位置在这里的时候,已经包含匹配好的数量
直接将第一个的值赋值为1就可以了
这里是采取匹配两次的方法,第一次求ne数组并初始化cnt
第二次是确保匹配的长度不会过大,也就是只有前面i/2个元素进行匹配,时间复杂度是o(n)
两次匹配,从而确保范围
*/
#include <bits/stdc++.h>
using namespace std;
const int M=1e6+5;
#define int long long
const int mod=1e9+7;
int ne[M],cnt[M];
//公共前缀在这里的话,匹配的数量,确实是这样的,先把第一个赋值为1就可以了
void kmp(string s,int n) {
cnt[1]=1;
for(int i=2,j=0;i<=n;i++) {
while(j&&s[i]!=s[j+1])j=ne[j];
if(s[i]==s[j+1])j++;
ne[i]=j;
cnt[i]=cnt[j]+1;
}
}
signed main() {
int TT;cin>>TT;
while(TT--) {
string s;cin>>s;
int n=s.length();s=' '+s;
kmp(s,n);
int ans=1;
//在这里用j控制第二个的长度,可以保证不会越界,复杂度也是可行的
for(int i=2,j=0;i<=n;i++) {
while(j&&s[i]!=s[j+1])j=ne[j];
if(s[i]==s[j+1])j++;
while(j>i/2)j=ne[j];
ans=ans*(cnt[j]+1)%mod;
}
cout<<ans<<endl;
}
return 0;
}
标签:cnt,匹配,int,ne,ans,动物园
From: https://www.cnblogs.com/basicecho/p/17306844.html