BZOJ3670: [Noi2014]动物园(DP)
2018-03-06 23:28
148 查看
前言
这道题理解KMP真是再好不过了,虽然和KMP没什么关系。但是这里核心就是处理KMP的next数组,而KMP的重难点也是next数组,所以对于刚刚学了KMP的少主来说真的是很恰到好处了。
题意
求出一个序列每一个前缀的不重合的相同前缀和后缀的个数。看不懂吧。。。。看这个
题目链接
分析
虽然说和KMP关系密切并且你必须会KMP,但实际上分析和KMP没啥关系。大概就是KMP的next数组有一个含义,而且题目给得很明确:next[i]就是在长度为[i]的字符串中前缀=后缀的最长长度。
有了后只需要不停地next,把满足题意的情况记下来即可。
直接暴力找肯定要TLE,亲测。
由于需要有长度限制,对于长度为i的字符串,找到了第一个长度在条件内的,那么剩下的长度都满足,就可以DP
但是如果暴力找第一个长度为i的字符串还是会超时,我们可以根据i比较大的找到的第一个满足条件的数一定比i比较小的找到的第一个满足条件的数大,直接上大步跳跃即可,慢了一点点而已。
如果不大步跳跃,也可以在求出了fail(next)数组后,用类似的方法求出满足长度要求的一个新的f数组,f数组就是第一个满足长度的条件,剩下的仍然是DP,因为没有递归要快一些。
顺便,memset其实是非常消耗时间的一个操作。
代码
//两个solve选一个即可#include<cctype> #include<cstdio> #include<cstring> #include<iostream> using namespace std; const int maxn=1e6+105,mod=1e9+7; int n; int num,fail[maxn],d[maxn],f[maxn]; char s[maxn]; int ff(int i,int n) { if(i*2<=n)return i; return f[i]=ff(f[i],n); } void solve()//大步跳跃 { gets(s); int ans=1; int n=strlen(s); int i=0,j=-1; fail[0]=-1; while(i<n) { while(j>=0 && s[i]!=s[j])j=fail[j]; i++,j++; fail[i]=j; } for(int i=1;i<=n;i++) { d[i]=d[fail[i]]+1; f[i]=fail[i]; } for(int i=n;i>=1;i--) { f[i]=ff(f[i],i); ans=1ll*ans*(d[f[i]]+1)%mod; } printf("%d\n",ans); } void solve()//再次递推求f { gets(s); int ans=1; int n=strlen(s); int i=0,j=-1; fail[0]=-1; while(i<n) { while(j>=0 && s[i]!=s[j])j=fail[j]; i++,j++; fail[i]=j; } i=0,j=-1; while(i<n) { while(j>=0 && ( s[i]!=s[j] || 2*(j+1)>(i+1) ))j=fail[j]; i++,j++; f[i]=j; } for(int i=1;i<=n;i++) { d[i]=d[fail[i]]+1; ans=1ll*ans*(d[f[i]]+1)%mod; } printf("%d\n",ans); } int main() { //freopen("in.txt","r",stdin); scanf("%d",&n); gets(s); while(n--) solve(); return 0; }
相关文章推荐
- bzoj3670 [Noi2014]动物园 kmp
- bzoj3670:NOI2014 动物园
- [KMP fail树] BZOJ3670: [Noi2014]动物园
- BZOJ3670(Noi2014)[动物园]--KMP
- BZOJ3670: [Noi2014]动物园
- 【bzoj3670】【NOI2014】【动物园】【kmp+dp】
- BZOJ3670 [Noi2014]动物园 解题报告【字符串】【KMP】
- BZOJ3670: [Noi2014]动物园
- bzoj3670【NOI2014】动物园
- BZOJ3670: [Noi2014]动物园(洛谷P2375)
- 【BZOJ】3670 [Noi2014]动物园 KMP
- [BZOJ]3670 [NOI]2014 动物园 KMP好题
- 【 bzoj 3670 】 [Noi2014]动物园 - KMP
- NOI 2014 动物园
- [NOI 2014]动物园
- 【bzoj3670】[Noi2014]动物园 KMP-next数组
- BZOJ 3670: [Noi2014]动物园 [KMP]
- BZOJ3670 & 洛谷2375 & UOJ5:[NOI2014]动物园——题解
- BZOJ3670【NOI2014】动物园(KMP变形)
- 【NOI2014】动物园