[bzoj3670] [NOI2014] [lg2375] 动物园
nxt数组为KMP的next数组
num[i]储存了i前面可以匹配的串的个数。
先在KMP求nxt中顺便求出num
最后再找到对于i的最大的前后缀不重叠的可匹配的j,ans*=(num[j]+1)%1000000007
ans即为答案
1 #include<cstdio> 2 #include<cstring> 3 using namespace std; 4 char s[1000100]; 5 int nxt[1000100],num[1000100],n; 6 long long ans; 7 void doit(char *s){ 8 int n=strlen(s); 9 nxt[0]=-1; 10 nxt[1]=0; 11 num[0]=0; 12 num[1]=1;ans=1; 13 for(int i=1,j=0;i<n;i++){ 14 while(j>=0&&s[i]!=s[j])j=nxt[j]; 15 nxt[i+1]=++j; 16 num[i+1]=num[j]+1; 17 } 18 for(int i=1,j=0;i<n;i++){ 19 while(j>=0&&s[i]!=s[j])j=nxt[j]; 20 j++; 21 while((j<<1)>(i+1))j=nxt[j]; 22 ans=(ans*((long long)num[j]+1))%1000000007; 23 } 24 printf("%lld\n",ans); 25 } 26 int main(){ 27 scanf("%d",&n); 28 while(n--){ 29 scanf("%s",s); 30 doit(s); 31 } 32 }