【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/ ...
随机推荐
- 请尽可能详尽的解释AJAX的工作原理
第一步:创建ajax对象(XMLHttpRequest/ActiveXObject(Microsoft.XMLHttp)) 第二步:判断数据传输方式(GET/POST) 第三步:打开链接 open() ...
- Python Twisted系列教程5:由Twisted支持的诗歌客户端
作者:dave@http://krondo.com/twistier-poetry/ 译者:杨晓伟(采用意译) 你可以从这里从头开始阅读这个系列 抽象地构建客户端 在第四部分中,我们构建了第一个使用 ...
- 使用Selenium登录新浪微博
为了总结一下Selenium的用法,具体用了这个例子来说明一下. Selenium简单来说,就是通过程序驱动一个浏览器,并且可以通过程序来帮你做一些事情,例如点击.填表呀之类的. 换句话说,你在浏览器 ...
- python学习——练习题(5)
""" 题目:输入三个整数x,y,z,请把这三个数由小到大输出. """ def inputInt(i): ""&quo ...
- JAVA 用axis1 调用.NET的web service
1.去官网下载axis的jar包,我下的是1.4版本的 http://axis.apache.org/axis/java/releases.html 2.JAVA 代码: public void my ...
- java之yield(),sleep(),wait()区别详解-备忘笔记(转)
1.sleep() 使当前线程(即调用该方法的线程)暂停执行一段时间,让其他线程有机会继续执行,但它并不释放对象锁.也就是说如果有synchronized同步快,其他线程仍然不能访问共享数据.注意该方 ...
- svn之merge
[svn之merge] 1. merge SOURCE[@REV] [TARGET_WCPATH] (the 'sync' merge) This form is called a 'sync' ( ...
- js 操作table
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default4.aspx.cs ...
- c语言实践:求两个数的最大公约数
我的思路是这样的:比如12和16这两个数.先理解一下概念,什么叫最大公约数.就是12有很多个因数,16也有很多个因数,这两堆因数中有一些重合的因数,在这些重合的因数中找到那个最大的.那么最大公约数一定 ...
- Luogu 3066 [USACO12DEC]逃跑的BarnRunning Away From…
好像是某CF的题,不记得…… 很套路的题,但是觉得可以做一下笔记. 倍增 + 差分. 有一个比较简单的思路就是每一个点$x$向上走一走,直到走到一个点$y$使总路程恰好不超过超过了$L$,然后把$(x ...