[bzoj3670]动物园
首先计算出s数组,s表示可以重复的前缀等于后缀的个数,显然有s[i]=s[next[i]]+1,因为有且仅有next的next满足这个条件。
然后直接暴力枚举所有next,直到它小于i的一半,这个时间复杂度就是o(n)的
1 #include<bits/stdc++.h> 2 using namespace std; 3 int t,ans,k,sum[1000005],nex[1000005]; 4 char s[1000005]; 5 int main(){ 6 scanf("%d",&t); 7 while (t--){ 8 scanf("%s",s); 9 k=0; 10 memset(nex,0,sizeof(nex)); 11 ans=sum[1]=1; 12 for(int i=1;s[i];i++){ 13 while ((k)&&(s[k]!=s[i]))k=nex[k]; 14 if (s[k]==s[i])k++; 15 nex[i+1]=k; 16 sum[i+1]=sum[k]+1; 17 } 18 k=0; 19 for(int i=1;s[i];i++){ 20 while ((k)&&(s[k]!=s[i]))k=nex[k]; 21 if (s[k]==s[i])k++; 22 while (2*k>i+1)k=nex[k]; 23 ans=ans*(sum[k]+1LL)%1000000007; 24 } 25 printf("%d\n",ans); 26 } 27 }