【改造KMP】洛谷P2375 动物园

匿名 (未验证) 提交于 2019-12-03 00:26:01

范围很狗,不要轻信!

https://www.luogu.org/problemnew/show/P2375

我们大家都知道 KMPnext数组吧(不知道也无所谓)
其定义是:
在字符串s从第1位开始长度为i的子串中,既是前缀又是后缀的最长的子串的长度(可以重叠)称为next[i]
先定义这样一个数组num:
在字符串s从第1位开始长度为i的子串中,既是前缀又是后缀的最长的子串的长度(不可重叠)称为next[i]
i=0n1(num[i]+1)

˼·

唉呀妈呀,好麻烦啊,我们充分理解之后就会发现
所有num[i]的两倍均小于i,所以我们就可以加个特判就行了

#include<cstdio> #include<cstring> #define mod 1000000007 using namespace std;int kmp[1000001],num[1000001],t,n; long long ans; char a[1000001]; int main() {     scanf("%d",&t);//t组数据     while(t--)     {         scanf("%s",a);n=strlen(a);         kmp[0]=-1;         kmp[1]=0;num[0]=0;         num[1]=1;//初始化         ans=1;//初始化         for(int i=1,j=0;i<n;)         if(j==-1||a[i]==a[j])          kmp[++i]=++j,num[i]=num[j]+1;         else j=kmp[j];//kmp算法         for(int i=1,j=0;i<n;i++)         {             while(j>=0&&a[i]!=a[j]) j=kmp[j];             j++;             while((j<<1)>(i+1)) j=kmp[j];//代码核心             ans*=(long long)num[j]+1;             ans%=mod;         }         printf("%lld\n",ans);//输出     } }
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!