[NOI2014]动物园(KMP,字符串)
半年前看这题还感觉很神仙,做不动(没看题解)。
现在过来看发现……这tm就是一个sb题……
首先题面已经提示我们用 KMP 了。那 KMP 究竟能干啥呢?
看 $num$ 的定义。发现对于前缀 $i$,$nxt[nxt[\dots nxt[i]]]$ 这个长度的前缀和后缀是相等的。
那么令 $cnt[i]=cnt[nxt[i]]+1$(其中 $cnt[0]=0$,也就是说在 $nxt$ 上跳能跳多少步),如果不考虑前缀后缀不重叠的限制,$num[i]=cnt[i]$。
那么限制怎么弄呢?其实就是要计算 $nxt[nxt[\dots nxt[i]]]\le \lfloor i/2\rfloor$ 的个数。
令 $pt[i]$ 为 $\le\lfloor i/2\rfloor$ 中最大的 $nxt[nxt[\dots nxt[i]]]$。那么 $num[i]=cnt[pt[i]]$。
可以用倍增做到 $O(n\log n)$。然而根本不用这么麻烦。
显然有 $pt[nxt[i]]\le pt[i]$。那么我们倒着做,求出 $pt[i]$ 之后,令 $pt[nxt[i]]=pt[i]$。每次求解 $pt[i]$ 时,不停跳 $nxt$ 直到合法为止。
根据 KMP 的复杂度分析可得复杂度为 $O(n)$。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=,mod=;
#define FOR(i,a,b) for(int i=(a);i<=(b);i++)
#define ROF(i,a,b) for(int i=(a);i>=(b);i--)
#define MEM(x,v) memset(x,v,sizeof(x))
inline int read(){
int x=,f=;char ch=getchar();
while(ch<'' || ch>'') f|=ch=='-',ch=getchar();
while(ch>='' && ch<='') x=x*+ch-'',ch=getchar();
return f?-x:x;
}
int t,n,nxt[maxn],cnt[maxn],pt[maxn];
char s[maxn];
int main(){
t=read();
while(t--){
scanf("%s",s+);
n=strlen(s+);
MEM(nxt,);MEM(cnt,);MEM(pt,-);
int j=nxt[]=;
FOR(i,,n){
while(j && s[i]!=s[j+]) j=nxt[j];
if(s[i]==s[j+]) j++;
nxt[i]=j;
}
FOR(i,,n) cnt[i]=cnt[nxt[i]]+;
ROF(i,n,){
if(pt[i]==-) pt[i]=i;
while(pt[i]>i/) pt[i]=nxt[pt[i]];
pt[nxt[i]]=pt[i];
}
int ans=;
FOR(i,,n) ans=1ll*ans*(cnt[pt[i]]+)%mod;
printf("%d\n",ans);
}
}
[NOI2014]动物园(KMP,字符串)的更多相关文章
- BZOJ3670:[NOI2014]动物园(KMP)
Description 近日,园长发现动物园中好吃懒做的动物越来越多了.例如企鹅,只会卖萌向游客要吃的.为了整治动物园的不良风气,让动物们凭自己的真才实学向游客要吃的,园长决定开设算法班,让动物们学习 ...
- BZOJ 3670: [Noi2014]动物园 [KMP]
求这玩意: 对于字符串S的前i个字符构成的子串,既是它的后缀同时又是它的前缀,并且该后缀与该前缀不重叠,将这种字符串的数量记作num[i] 对1,000,000,007取模的结果 n≤5,L≤1,00 ...
- BZOJ 3670 NOI2014 动物园 KMP+dp
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3670 题意概述:令num[i]表示字符串由1~i的字符形成的前缀中不相重叠的相同前后缀的数 ...
- [NOI2014]动物园(kmp)
题目 https://www.luogu.org/problemnew/show/P2375 做法 查找多少个前缀与后缀配对,其实就是\(fail\)树的深度 而不可重叠,其实\(i\)不可用的,\( ...
- P2375 [NOI2014]动物园 KMP
好,暴力能拿$50pts\space qwq$ 暴力的思路就是一直跳$nxt[j]$,直到它的长度小于串的一半,然后开始计数,当然要接着跳$nxt[j]$ 正解:考虑没有长度要求的(不要求不重合)公共 ...
- bzoj3670 [Noi2014]动物园——KMP
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3670 第一次写KMP算法...又T又WA了半天... 1. num 数组表示包括其本身的前缀 ...
- 字符串(KMP):BZOJ 3670 [Noi2014]动物园
3670: [Noi2014]动物园 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 1521 Solved: 813[Submit][Status] ...
- BZOJ 3670: [Noi2014]动物园【KMP变形 】
3670: [Noi2014]动物园 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 2738 Solved: 1475[Submit][Status ...
- BZOJ3670 [Noi2014]动物园 【KMP计数】
3670: [Noi2014]动物园 Time Limit: 10 Sec Memory Limit: 512 MB Submit: 3143 Solved: 1690 [Submit][Stat ...
- 【bzoj3670】: [Noi2014]动物园 字符串-kmp-倍增
[bzoj3670]: [Noi2014]动物园 一开始想的是按照kmp把fail算出来的同时就可以递推求出第i位要f次可以跳到-1 然后把从x=i开始顺着fail走,走到fail[x]*2<i ...
随机推荐
- github上方便的小工具
目录 python中的fire模块 Install Reference python中的fire模块 它可以对所有Python 对象,包括functions, classes, modules, ob ...
- mybatis的参数传递
mybatis的参数传递分为两种:1.单参数传递 2.多参数传递 单参数 mybatis会直接取出参数值给Mapper文件赋值 例子如下: 1.Mapper文件内容如下: public void d ...
- axios 源码解析(下) 拦截器的详解
axios的除了初始化配置外,其它有用的应该就是拦截器了,拦截器分为请求拦截器和响应拦截器两种: 请求拦截器 ;在请求发送前进行一些操作,例如在每个请求体里加上token,统一做了处理如果以后要 ...
- python学习笔记 - socket通信
socket socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,应用程序通常通过"套接字"向网络发出请求或者应答网络请求. sock ...
- 镭神激光雷达对于Autoware的适配
1. 前言 我们的自动驾驶采用镭神激光雷达,在使用Autoware的时候,需要对镭神激光雷达的底层驱动,进行一些改变以适配Autoware. 2. 修改 (1)首先修改lslidar_c32.laun ...
- 如何在 C# 中自定义 Comparer,以实现按中文拼音(a-z)来排序
1. 为何要自定义 Comparer a. 先看如下代码 class Program { public static void Main(string[] args) { List<string ...
- EntityFrameworkCore 学习笔记之示例一
直接贴代码了: 1. Program.cs using Microsoft.EntityFrameworkCore; using System; using System.Threading.Task ...
- 云原生时代, Kubernetes 多集群架构初探
为什么我们需要多集群? 近年来,多集群架构已经成为“老生常谈”.我们喜欢高可用,喜欢异地多可用区,而多集群架构天生就具备了这样的能力.另一方面我们也希望通过多集群混合云来降低成本,利用到不同集群各自的 ...
- Java问题记录——IllegalMonitorStateException
Java问题记录——IllegalMonitorStateException 摘要:本文主要分析了IllegalMonitorStateException的产生原因. 部分内容来自以下博客: http ...
- cent OS 7 安装谷歌浏览器
我直接写一个shell 脚本, install_google.sh, bash 命令直接运行就好, 脚本内容如下: (切换root用户执行) set -e # 出错即退出 echo " ...