[NOI2014]动物园

复习一下kmp,结果发现真的需要复习。
本题很水,思路很明显,但是有个咸鱼kmp打错这也。。。sad
做两遍kmp,然后发现如果nxt的长度<=i/2即可乘。
(出题人语文水平需要加强)

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int N=1e7+5,mod=1e9+7;
char s[N];
int nxt[N],len;
long long ans[N],mul;
void kmp() {
	ans[0]=0;ans[1]=1;
	int j=0;
	nxt[0]=-1;
	for(int i=2;i<=len;i++) {
		while(j>0&&s[i]!=s[j+1]) j=nxt[j];
		if(s[i]==s[j+1]) j++;
		nxt[i]=j;ans[i]=ans[j]+1ll;
	}
}
void get() {
	int j=0;
	for(int i=2;i<=len;i++) {
		while(j>0&&s[i]!=s[j+1]) j=nxt[j];
		if(s[i]==s[j+1])j++;
		if(j*2>i) j=nxt[j];
		mul=mul*(ans[j]+1ll)%mod;
	}
}
int main() {
	int T;
	scanf("%d",&T);
	while(T--) {
		mul=1;memset(nxt,0,sizeof nxt);memset(ans,0,sizeof ans);
		scanf("%s",s+1);
		len=strlen(s+1);
		kmp();
		get();
		printf("%lld\n",mul);
	}
}
posted @ 2018-07-15 20:19  SWHsz  阅读(99)  评论(0编辑  收藏  举报