[省选前题目整理][BZOJ 3670][NOI 2014]动物园(KMP)
2015-04-08 10:18
344 查看
题目链接
http://www.lydsy.com/JudgeOnline/problem.php?id=3670思路
为了方便叙述,下面所说的前缀ii就是字符串中的区间[1,i][1,i]对应的子串根据KMP定义,next[i]=jnext[i]=j表示前缀j前缀j满足既是前缀ii的前缀,又是前缀ii的后缀,且jj是最大的。(其实题目里对此也有说明)
然后我们可以根据next[]next[]数组构造一个cnt[]cnt[]数组,cnt[i]=cnt[i]=满足既是前缀ii的前缀,又是前缀ii的后缀的子串个数,这个数组可以通过递推在O(n)O(n)时间内得出:
cnt[1]=1cnt[1]=1
cnt[i]=cnt[next[i]]+1cnt[i]=cnt[next[i]]+1
然后我们可以通过cnt[]和next[]cnt[]和next[]数组得到num[]num[]数组。具体做法是,对于每个i>=2i>=2(i=1i=1时显然num[i]=0num[i]=0),通过沿着next[]next[]指针向前走找到最大的jj,jj满足前缀jj既是前缀ii的前缀,也是它的后缀,且2j<=i2j<=i(即题面中所限制的前缀和后缀不重叠),那么num[i]=cnt[j]num[i]=cnt[j]。
代码
#include <iostream> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <algorithm> #define MAXN 1000100 #define MOD 1000000007 using namespace std; typedef long long int LL; LL ans=0; char s[MAXN]; int next[MAXN],cnt[MAXN]; //cnt[i]=既是1~i的后缀又是它的前缀的字符串个数 void getnext(char str[],int len) { int k=0; next[1]=0; cnt[1]=1; //!!!!!! for(int i=2;i<=len;i++) { while(k>0&&str[k+1]!=str[i]) k=next[k]; if(str[k+1]==str[i]) k++; next[i]=k; cnt[i]=cnt[k]+1; } } LL work(char str[],int len) { int k=0; ans=1; for(int i=2;i<=len;i++) //用next[]和cnt[]数组求出num[i] { while(k&&str[k+1]!=str[i]) k=next[k]; if(str[k+1]==str[i]) k++; while((k*2)>i) k=next[k]; ans=(ans*(cnt[k]+1))%MOD; } return ans; } int main() { int T; scanf("%d",&T); while(T--) { scanf("%s",s+1); int len=strlen(s+1); getnext(s,len); printf("%lld\n",work(s,len)); } return 0; }
相关文章推荐
- [NOI2014][bzoj3670] 动物园 [kmp+next数组应用]
- 【KMP】[Noi2014] bzoj3670 动物园
- bzoj3670: [Noi2014]动物园 KMP
- 【KMP】BZOJ3670-[Noi2014]动物园
- [BZOJ3670][Noi2014]动物园 KMP
- 字符串(KMP):BZOJ 3670 [Noi2014]动物园
- [KMP next树] BZOJ 3670 [Noi2014]动物园
- 【BZOJ】3670 [Noi2014]动物园 KMP
- 【BZOJ3670】【NOI2014】动物园 KMP变形 线性出解
- BZOJ 3670: [Noi2014]动物园【KMP变形 】
- BZOJ 3670 [Noi2014]动物园 (KMP next数组应用)
- bzoj 3670: [Noi2014]动物园 kmp与扩展kmp
- [BZOJ3670][NOI2014]动物园(KMP)
- 【KMP,next树】BZOJ3670 [Noi2014]动物园
- BZOJ 3670: [Noi2014]动物园 KMP题解
- BZOJ 3670 [Noi2014] 动物园 KMP
- 【BZOJ3670】【NOI2014】动物园 [KMP][倍增]
- bzoj 3670 [Noi2014]动物园【kmp】
- BZOJ 3670: [Noi2014]动物园(kmp+递推)
- [BZOJ3670][Noi2014]动物园 && KMP