P2375 [NOI2014] 动物园
P2375 [NOI2014] 动物园
题目描述
近日,园长发现动物园中好吃懒做的动物越来越多了。例如企鹅,只会卖萌向游客要吃的。为了整治动物园的不良风气,让动物们凭自己的真才实学向游客要吃的,园长决定开设算法班,让动物们学习算法。
某天,园长给动物们讲解 KMP 算法。
园长:“对于一个字符串
熊猫:“对于字符串
园长:“非常好!那你能举个例子吗?”
熊猫:“例
园长表扬了认真预习的熊猫同学。随后,他详细讲解了如何在
下课前,园长提出了一个问题:“KMP 算法只能求出
最后,园长给出了奖励条件,第一个做对的同学奖励巧克力一盒。听了这句话,睡了一节课的企鹅立刻就醒过来了!但企鹅并不会做这道题,于是向参观动物园的你寻求帮助。你能否帮助企鹅写一个程序求出
特别地,为了避免大量的输出,你不需要输出
数据范围
Solution:
首先我们注意到 ,
然后我们要求的
记
我们思考为什么:
图中红色表示
我们把图画出来了之后,不难发现这样做是能保证每次跳到的
那么我们如何保证答案符合不超过一半长度的限制呢? 回顾一下我们求
Code:
#include<bits/stdc++.h> #define ll long long const int N=1e6+6; const int mod=1e9+7; using namespace std; ll mul(ll x,ll y){return x*y%mod;} ll nxt[N],cnt[N],n; char c[N]; ll ans; void work() { scanf("%s",c+1); n=strlen(c+1); cnt[1]=1; ans=1; int j=0; for(int i=0;i<=n;i++)nxt[i]=0; for(int i=2;i<=n;i++) { while(j&&c[j+1]!=c[i])j=nxt[j];j+=(c[j+1]==c[i]); nxt[i]=j;cnt[i]=cnt[j]+1; } j=0; for(int i=2;i<=n;i++) { while(j&&c[j+1]!=c[i])j=nxt[j];j+=(c[j+1]==c[i]); while((j<<1)>i)j=nxt[j]; ans=mul(ans,cnt[j]+1); } printf("%lld\n",ans); } int main() { //freopen("P2375.in","r",stdin);freopen("P2375.out","w",stdout); int T;cin>>T; while(T--)work(); return 0; }