[NOI2014][bzoj3670] 动物园 [kmp+next数组应用]
题面
思路
首先,这题最好的一个地方,在于它给出的关于$next$的讲解实在是妙极......甚至可以说我的kmp是过了这道题以后才脱胎换骨的
然后是正文:
如何求$num$数组?
这道题的输入有1e6个字符,显然需要$O\left(n\right)$左右级别的算法来解
先看到$num$的定义:不互相重叠的公共前后缀个数
这说明什么?
说明$num$不同于$next$记录的是一个最大值,它记录的是一个和值
而这个和值,是可以推出来的
考虑一个前缀$i$的$next[i]$,它长这样:

其中,$next[i]$,$next[next[i]]$,$next[next[next[i]]]$......都是这个前缀串i的公共前后缀,而且只有它们是公共前后缀
那么,我们其实只要在求$next$的过程中,顺便把这个公共前后缀的数量递推一下,就得到了一个弱化版的$num$数组:可以重叠的公共前后缀数量,我们称之为$ans$
如何去除有重叠的?
还是看上面那张图
首先$next$数组有一个性质:$next[i] < i$
也就是说,一旦有一个递归了n层的next,比原前缀i的长度的一半要小,那么这个next的递推出的答案$ans$就是i的$num$了
一个问题
假如我们拿到的串是1e6个'a',那么上面那个算法就会被卡成$O\left(n^2\right)$,道理的话大家可以想一想(每一次递归都只会把next[i]变小1)
那么我们需要做一个优化,来解决这个问题,而解决问题的核心就是:减少重复递归
减少重复递归......有没有想到什么?
没错,就是如同求$next$时一样的方法!
我们将递归用的变量$j$的值不更新,这样,求完了$i$的答案以后,$j$的位置一定在$\frac i2$的左边,也就是它已经满足要求了
这时再递归求解,总时间效率是$O\left(n\right)$的
Code
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const ll MOD=1e9+7;
int n,fail[1000010],ans[1000010];ll cnt;char a[1000010];
int main(){
int T,i,j;scanf("%d",&T);
while(T--){
scanf("%s",a);n=strlen(a);
memset(fail,0,sizeof(fail));
j=0;ans[0]=0;ans[1]=1;
for(i=1;i<n;i++){//求解next
while(j&&(a[i]!=a[j])) j=fail[j];
j+=(a[i]==a[j]);fail[i+1]=j;ans[i+1]=ans[j]+1;//递推记录ans
}
j=0;cnt=1;
for(i=1;i<n;i++){//求解num
while(j&&(a[i]!=a[j])) j=fail[j];
j+=(a[i]==a[j]);
while((j<<1)>(i+1)) j=fail[j];
cnt=(cnt*(ll)(ans[j]+1))%MOD;//记得+1
}
printf("%lld\n",cnt);
}
}
[NOI2014][bzoj3670] 动物园 [kmp+next数组应用]的更多相关文章
- uoj #5. 【NOI2014】动物园 kmp
#5. [NOI2014]动物园 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://uoj.ac/problem/5 Description 近日 ...
- 【BZOJ3670】【NOI2014】动物园 [KMP][倍增]
动物园 Time Limit: 10 Sec Memory Limit: 512 MB[Submit][Status][Discuss] Description 近日,园长发现动物园中好吃懒做的动物 ...
- BZOJ-3670 动物园 KMP+奇怪的东西
YveH爷再刷KMP,DCrusher看他刷KMP,跟着两个人一块刷KMP... 3670: [Noi2014]动物园 Time Limit: 10 Sec Memory Limit: 512 MB ...
- 【NOI2014】动物园 - KMP
题目描述 近日,园长发现动物园中好吃懒做的动物越来越多了.例如企鹅,只会卖萌向游客要吃的.为了整治动物园的不良风气,让动物们凭自己的真才实学向游客要吃的,园长决定开设算法班,让动物们学习算法. 某天, ...
- LG2375/LOJ2246 「NOI2014」动物园 KMP改造
问题描述 LG2375 LOJ2246 题解 看了题解,需要回看,需要继续通过本题深入理解KMP. 为了将 \(\mathrm{KMP}\) 和只插入了一个模式串的\(\mathrm{AC}\)自动机 ...
- UOJ #5. 【NOI2014】动物园 扩大KMP
第一次NOI称号. ... 扩展假设知道KMP如果. .. . 就是水题了. ... #5. [NOI2014]动物园 统计提交情况 描写叙述 提交 近日.园长发现动物园中好吃懒做的动物越来越多了.比 ...
- uoj #5. 【NOI2014】动物园
#5. [NOI2014]动物园 近日,园长发现动物园中好吃懒做的动物越来越多了.例如企鹅,只会卖萌向游客要吃的.为了整治动物园的不良风气,让动物们凭自己的真才实学向游客要吃的园长决定开设算法班,让 ...
- HDU 1358 Period(KMP next数组运用)
Period Problem Description For each prefix of a given string S with N characters (each character has ...
- 【BZOJ3670】【NOI2014】动物园(KMP算法)
[BZOJ3670]动物园(KMP算法) 题面 BZOJ 题解 神TM阅读理解题 看完题目之后 想暴力: 搞个倍增数组来跳\(next\) 每次暴跳\(next\) 复杂度\(O(Tnlogn)\) ...
随机推荐
- pytho线程信号量
pytho线程信号量 import threading,time def going(num,sleep_time): semaphore.acquire()#启动允许执行 print("g ...
- React后台管理系统-file-uploader组件
1.React文件上传组件github地址: https://github.com/SoAanyip/React-FileUpload 2.Util里边新建file-uploader文件夹,里边新建i ...
- leetcode - 二叉树最大深度
二叉树最大深度 给定一个二叉树,找出其最大深度. 二叉树的深度为根节点到最远叶子节点的最长路径上的节点数. 说明: 叶子节点是指没有子节点的节点. 示例: 给定二叉树 [3,9,20,null,nul ...
- 算法竞赛入门经典5.1 从c到c++
这个章节主要是讲述了一些c++的特性,在这里面,对我用处最大的应该就是字符串吧.首先是getline,getchar,stringstream的使用了吧. 首先介绍这三个函数. 1. getline函 ...
- ZR#317.【18 提高 2】A(计算几何 二分)
题意 Sol 非常好的一道题,幸亏这场比赛我没打,不然我估计要死在这个题上qwq 到不是说有多难,关键是细节太多了,我和wcz口胡了一下我的思路,然后他写了一晚上没调出来qwq 解法挺套路的,先提出一 ...
- 十三、MySQL WHERE 子句
MySQL WHERE 子句 我们知道从 MySQL 表中使用 SQL SELECT 语句来读取数据. 如需有条件地从表中选取数据,可将 WHERE 子句添加到 SELECT 语句中. 语法 以下是 ...
- Linux-SSH远程登陆
SSH是什么 Secure Shell 安全外壳协议 建立在应用层基础上的安全协议 可靠.转为远程登陆会话和其他网络提供安全性的协议 SSH客户端是用于多种平台 服务器安装SSH服务 安装:yum i ...
- SQL Server中的日期,时间组合查询
如图所示,Jdate和Jdate2是两个分开的字段,一个是date类型,存储日期,一个是time(0)类型,存储具体时间 现在有这样的要求,就是获得(Jdate和Jdate2组合起来的日期时间)在(当 ...
- music21 关联 MuseScore 和 Lilypond
在python安装 music21后,需要关联 musescore 或 lilypond 才能可以用图形化的形式看到 乐谱. 因此 在安装 music21后,需要配置环境变量,yvivid 在 mus ...
- 2017 ACM/ICPC Shenyang Online SPFA+无向图最长路
transaction transaction transaction Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 132768/1 ...