首页 > 代码库 > [bzoj3670] [NOI2014][lg2375] 动物园

[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 }

 

[bzoj3670] [NOI2014][lg2375] 动物园