【bzoj3670】: [Noi2014]动物园 字符串-kmp-倍增
一开始想的是按照kmp把fail算出来的同时就可以递推求出第i位要f次可以跳到-1
然后把从x=i开始顺着fail走,走到fail[x]*2<i 然后ans*=f[fail[x]]+1 就好了?
但是发现显然会变成O(n^2) TLE。。
于是就想到了倍增fail[i][j]就是第i位顺着fail 跳了 2^j 的位置
好像很对的样子就把O(nlogn)的交了一发好像还是TLE了。。
我可能需要W(卡)Y(常)S(数) 优化。。把fail[i][j] 换成 第j位顺着fail跳了2^i 次
似乎一下快了好多 然后4s AC了。。
/* http://www.cnblogs.com/karl07/ */
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <cstdio>
using namespace std; #define P 1000000007
int T,fail[][],num,f[],Fail[];
char s[];
long long ans; void work(){
scanf("%s",s+);
f[]=,Fail[]=-,ans=;
for (int i=;i<=;i++) fail[i][]=-;
for (int i=,l=strlen(s+);i<=l;i++){
Fail[i]=Fail[i-];
while (s[Fail[i]+]!=s[i] && Fail[i]!=-) Fail[i]=Fail[Fail[i]];
fail[][i]=++Fail[i];
for (int j=;j<=;j++) fail[j][i]= fail[j-][i]==- ? - : fail[j-][fail[j-][i]];
num=fail[][i];
for (int j=;j>=;j--) fail[j][num]*>i ? num=fail[j][num] : ;
if (num!= && num*>i) num=fail[][num];
f[i]=f[Fail[i]]+;
ans=(ans*(f[num]+))%P;
}
printf("%lld\n",ans);
} int main(){
scanf("%d\n",&T);
while (T--) work();
return ;
}
奇怪的倍增
然后发现正解是维护fail1和fail2。。fail1一个是原来的fail,fail2[x]是fail1[x]跳到fail[x]*2<i的结果
其实fail2可以跟着fail1一起递推,初始值换一下就好了。。
/* http://www.cnblogs.com/karl07/ */
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <cstdio>
using namespace std; #define P 1000000007
int T,fail[],num,f[],Fail[];
char s[];
long long ans; void work(){
scanf("%s",s+);
f[]=,Fail[]=fail[]=-,ans=;
for (int i=,l=strlen(s+);i<=l;i++){
Fail[i]=Fail[i-];
fail[i]=fail[i-];
while (s[Fail[i]+]!=s[i] && Fail[i]!=-) Fail[i]=Fail[Fail[i]];
while (s[fail[i]+]!=s[i] && fail[i]!=-) fail[i]=Fail[fail[i]];
++Fail[i];
++fail[i];
while (fail[i]*>i) fail[i]=Fail[fail[i]];
f[i]=f[Fail[i]]+;
ans=(ans*(f[fail[i]]+))%P;
}
printf("%lld\n",ans);
} int main(){
scanf("%d\n",&T);
while (T--) work();
return ;
}
正解
【bzoj3670】: [Noi2014]动物园 字符串-kmp-倍增的更多相关文章
- BZOJ3670 [Noi2014]动物园 【KMP计数】
3670: [Noi2014]动物园 Time Limit: 10 Sec Memory Limit: 512 MB Submit: 3143 Solved: 1690 [Submit][Stat ...
- 【BZOJ3670】动物园(KMP算法)
[BZOJ3670]动物园(KMP算法) 题面 BZOJ 题解 神TM阅读理解题 看完题目之后 想暴力: 搞个倍增数组来跳\(next\) 每次暴跳\(next\) 复杂度\(O(Tnlogn)\) ...
- BZOJ 3670: [Noi2014]动物园【KMP变形 】
3670: [Noi2014]动物园 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 2738 Solved: 1475[Submit][Status ...
- bzoj千题计划250:bzoj3670: [Noi2014]动物园
http://www.lydsy.com/JudgeOnline/problem.php?id=3670 法一:KMP+st表 抽离nxt数组,构成一棵树 若nxt[i]=j,则i作为j的子节点 那么 ...
- BZOJ3670:[NOI2014]动物园(KMP)
Description 近日,园长发现动物园中好吃懒做的动物越来越多了.例如企鹅,只会卖萌向游客要吃的.为了整治动物园的不良风气,让动物们凭自己的真才实学向游客要吃的,园长决定开设算法班,让动物们学习 ...
- [BZOJ3670] [NOI2014] 动物园 解题报告 (KMP)
题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=3670 Description 近日,园长发现动物园中好吃懒做的动物越来越多了.例如企鹅, ...
- [NOI2014]动物园(KMP,字符串)
半年前看这题还感觉很神仙,做不动(没看题解). 现在过来看发现……这tm就是一个sb题…… 首先题面已经提示我们用 KMP 了.那 KMP 究竟能干啥呢? 看 $num$ 的定义.发现对于前缀 $i$ ...
- bzoj3670 [Noi2014]动物园——KMP
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3670 第一次写KMP算法...又T又WA了半天... 1. num 数组表示包括其本身的前缀 ...
- BZOJ3670 [Noi2014]动物园
本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...
随机推荐
- 缓存 memcached 与 redis
Memcached Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载.它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态.数据库驱动网站的速度 ...
- Android 4 学习(12):Linkify & Broadcast event
参考<Professional Android 4 Development> Linkify Linkfy类可以在Text View中创建超链接.匹配LInkify中正则表达式的文本将被L ...
- Android 4 学习(11):Intent简介
参考<Professional Android 4 Development> Intents 本文主要从这几个方面介绍Intents: 使用Intents在Android程序内部或外部通信 ...
- Java之匿名内部类和包装类
匿名内部类 作用: 假如某个类只使用一次,则可以使用匿名内部类,无需再新建该类 我们上下代码: package com.learn.chap03.sec16; /** * 定义接口 */ public ...
- Xamarin官方示例代码无法部署,提示已跳过部署解决方法
最近利用Visual Studio 2017学习Android开发.主要是通过Xamarin官方的文档进行的.官方的入门指导提供了很多的示例代码.但是下载之后,调试运行的时候,总是无法部署到虚拟机上. ...
- spring注解开发的准备工作
- json_encode和json_decode和isset和array_key_exists
1.json_decode() json_decode — 对 JSON 格式的字符串进行编码 说明 mixed json_decode ( string $json [, bool ...
- 661. Image Smoother色阶中和器
[抄题]: Given a 2D integer matrix M representing the gray scale of an image, you need to design a smoo ...
- java面试题 级hr解答 非技术问题 !=!=未看
Java基础 ● 集合类以及集合框架:HashMap与HashTable实现原理,线程安全性,hash冲突及处理算法:ConcurrentHashMap: ● 进程和线程的区别: ● Java的并发. ...
- c语言实践 给三个数输出最大的那个数
我是怎么想的,我前面学过两个数比大小,比如有三个数,a b c,先比较a和b的大小,然后用那个较大的和c比较就得出最大的那个了.这个求三个数比大小的问题最后变化成 了两个数比大小了. int main ...