BZOJ3670(Noi2014)[动物园]--KMP

来源:互联网 发布:大麦盒子刷机 网络限制 编辑:程序博客网 时间:2024/05/16 06:46

【链接】
bzoj3670

【解题报告】

好像题目自己说是KMP。。。

就只需要判断一下失配指针的位置是否超过长度一半就行了。

#include<cstdio>#define LL long longusing namespace std;const int maxn=1000005,tt=1000000007;int T,len,a[maxn],p[maxn];LL ans;char s[maxn];void Readc(){    char ch=getchar(); len=0;    while (ch<'a'||ch>'z') ch=getchar();    while (ch>='a'&&ch<='z') s[++len]=ch,ch=getchar();}void Work(){    Readc(); ans=1; p[0]=p[1]=a[0]=0; a[1]=1;    for (int i=2,k1=0,k2=0; i<=len; i++)    {        while (k1&&s[k1+1]!=s[i]) k1=p[k1];        if (s[k1+1]==s[i]) k1++;        p[i]=k1; a[i]=a[k1]+1;        while (k2&&s[k2+1]!=s[i]) k2=p[k2];        if (s[k2+1]==s[i]) k2++;        while (k2>(i>>1)) k2=p[k2];        ans=(LL)ans*(a[k2]+1)%tt;    }    printf("%d\n",ans);}int main(){    freopen("3670.in","r",stdin);    freopen("3670.out","w",stdout);    scanf("%d",&T);    while (T--) Work();    return 0;}
原创粉丝点击