遠夏的动物园 2018-02-06
像求next一样求num。
第二次求next时加上不超过一半的条件。
时间复杂度: $ \huge O ( n ) $
![【BZOJ】3670: [Noi2014]动物园(KMP) 【BZOJ】3670: [Noi2014]动物园(KMP)](https://cdn.ancii.com/article/image/v1/hA/2T/nz/zn2ATh_sf1T7-NELomn6VFd7-JdCexwYUNpSQQVDxEt18mMMcNN1EqSxWFd_d5AW8Hgp5eXc5Vc1NBlDCUOmNVhEZbRBjFofTCi-AF8Nb7A.gif)
![【BZOJ】3670: [Noi2014]动物园(KMP) 【BZOJ】3670: [Noi2014]动物园(KMP)](https://cdn.ancii.com/article/image/v1/hA/2T/nz/zn2ATh_sf1T7-NELomn6VFd7-JdCexwYUNpSQQVDxEsbAxo9ve5UuWo5RuKiok9rI33vbk_IppfqJQRUf_FgSE0XS98FJNrY4jFPuXBea48.gif)
// luogu-judger-enable-o2
#include <bits/stdc++.h>
using namespace std;
const int MOD=;
int n, nxt[], num[];
char s1[];
long long ans;
void kmp()
{
ans=;
nxt[]=-; num[]=;
for(int i=,j;i<=n;i++)
{
for(j=nxt[i-]; j>= && s1[i]!=s1[j+]; j=nxt[j]);
j++; nxt[i]=j;
num[i]=num[j]+;
}
for(int i=,j=-;i<=n;i++)
{
for(; j>= && s1[i]!=s1[j+]; j=nxt[j]);
j++; //nxt[i]=j;
for(;(j<<)>i;j=nxt[j]);
ans*=num[j]+;ans%=MOD;
}
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%s",s1+);
n=strlen(s1+)+;
kmp();
printf("%lld\n",ans);
}
return ;
}View Code【洛谷】P3919 【模板】可持久化数组(主席树)