题解 P2375 【[NOI2014]动物园】

luogu

思路

先用裸的\(KMP\)求出\(fail(next)\)数组(随便叫的无所谓啦)和不管重叠时的数量记为\(ans_{i}\)\(ans\)的定义类似于\(fail(next)\),然后再跑一遍,求出\(<=\frac{i}{2}\)的数量,可结合代码理解

Code

#include<bits/stdc++.h>
using namespace std;
int n,l,fail[1000010],j,ans[1000010];
long long ANS,mod=1000000007;
char s[1000010];
int main()
{
	scanf("%d",&n);
	while(n--)
	{
		ANS=1;
		ans[1]=1;
		scanf("%s",s+1);
		l=strlen(s+1);
		j=0;
		for(int i=2;i<=l;i++)
		{
			while(j&&s[j+1]!=s[i])
			{
				j=fail[j];
			}
			if(s[j+1]==s[i])
			{
				fail[i]=++j;
			}
			else
			{
				fail[i]=0;
			}
			ans[i]=ans[j]+1;
		}
		j=0;
		for(int i=2;i<=l;i++)
		{
			while(j&&s[j+1]!=s[i])
			{
				j=fail[j];
			}
			j+=(s[j+1]==s[i]);
			while(j*2>i)
			{
				j=fail[j];
			}
			ANS=ANS*(ans[j]+1)%mod;
		}
		cout<<ANS<<endl;
	} 
}
posted @ 2019-07-17 10:04  G_A_TS  阅读(388)  评论(0编辑  收藏  举报