记录编号 291053 评测结果 AAAAAAAAAA
题目名称 [NOI 2014]动物园 最终得分 100
用户昵称 Gravatar安呐一条小咸鱼。 是否通过 通过
代码语言 C++ 运行时间 0.340 s
提交时间 2016-08-07 10:05:51 内存使用 8.90 MiB
显示代码纯文本
#include<iostream>
#include<cstdio>
#include<cstring>
#define maxn 1000010
#define mod 1000000007
using namespace std;
char ch[maxn];
int n,next[maxn],num[maxn],ans,k;
void getnext(){
	num[1]=1;
	for(int i=2;i<=n;i++){
		int j=next[i-1];
		while(j&&ch[j+1]!=ch[i])j=next[j];
		if(ch[j+1]==ch[i])j++;
		next[i]=j;
		num[i]=num[j]+1;
			/*
		如果暂时不考虑重叠的子串个数用num[i]表示,利用next表的性质,一定有num[i]=num[next[i]]+1;
		num[next[i]]表示next[i]之前的能够满足性质的子串个数,而i和next[i]是完全重合的一段,
		所以num[i]=num[next[i]]+1(i和next[i]也满足性质,所以+1) 目前都不考虑重叠的情况,
		如果能重复的话那么任何串自己和自己就可以算是一组,所以边界条件num[1]=1,记得是考虑重复!
		在求next的时候顺便求出num来就好了 
		*/
	}
}
int main(){
	freopen("zoo.in","r",stdin);freopen("zoo.out","w",stdout);
	int T;cin>>T;
	while(T--){
		scanf("%s",ch+1);
		n=strlen(ch+1);
		getnext();
		ans=1,k=0;
		for(int i=2;i<=n;i++){
			while(k&&ch[k+1]!=ch[i])k=next[k];//一直跳 
			if(ch[k+1]==ch[i])k++;
			while(k*2>i)k=next[k];
			ans=(1LL*ans*(num[k]+1))%mod;
		}
		/*
		现在考虑不能重叠那么j应该满足j<=i/2 所以在第二次扫过的时候只要j不满足条件,j=next[j]。答案乘上cnt[j]+1就好
		第二次求的时候j跳的时候和求next是相同的,不过是j必须要小于i/2,实际上求得是小于i/2的 能和i匹配上的位置。
		*/
		printf("%d\n",ans);
	}
	return 0;
}