扩展kmp学习笔记
kmp没写过,扩展kmp没学过可还行。
两个愿望,一次满足
(该博客仅用于防止自己忘记,不保证初学者能看懂我在瞎bb什么qwq)
用途
对于串\(s1,s2\),可以求出\(s2\)与\(s1\)的每个后缀的最长公共前缀。
(其实SA也可以干这事,只不过复杂度多个\(\log\)可能会被卡)
思想
与kmp一样,主要是充分利用已经得到的信息来往下推,以降低复杂度。
暴力
\(O(n^2)\)暴力扫,相信大家都会?
优化
记\(s[l,r]\)表示\(s\)在\([l,r]\)的子串。
考虑这样一件事:假如\(s2[1,k]=s1[1,k]\),那么就可以知道\(s2[2,k]=s1[2,k]\)。
假如再知道\(s2[2,p]=s2[1,p-1]\),那么就可以推出\(s2[1,\min(p,k)-1]=s1[2,k]\)了。
\(s2[2,p]=s2[1,p-1]\)正是kmp中\(s2\)的\(nxt\)数组,于是这样就可以完成一次转移。
然而这样转移并不是很优:当\(p<k\)时显然不能再往后推,但\(p>k\)时往后推还需要\(O(n)\)的时间,总复杂度仍然是\(O(n^2)\)的。
但我们可以记录之前最大的\(k\)在哪里,于是\(k_{max}\)单调递增,复杂度就有保证了。
代码
由于求nxt和求ex代码非常像,于是缩到了一起。
int n,m;
char s1[sz],s2[sz];
int nxt[sz],ex[sz];
void ExKmp(char *s1,char *s2,int *nxt,int *ex)
{
int len1=strlen(s1+1),len2=strlen(s2+1);
if (s1!=s2) for (ex[1]=0;s1[ex[1]+1]==s2[ex[1]+1]&&ex[1]<min(len1,len2);ex[1]++);
else {nxt[1]=len1;while (s1[nxt[2]+1]==s1[nxt[2]+2]&&nxt[2]+2<=len1) ++nxt[2];}
int p=1+(s1==s2);
rep(i,2+(s1==s2),len1)
{
if (i+nxt[i-p+1]<p+ex[p]) ex[i]=nxt[i-p+1];
else
{
int k=max(p+ex[p]-i,0);
while (s1[i+k]==s2[k+1]) ++k;
ex[i]=k;p=i;
}
}
}
int main()
{
file();
cin>>(s1+1)>>(s2+1);
n=strlen(s1+1),m=strlen(s2+1);
ExKmp(s2,s2,nxt,nxt);ExKmp(s1,s2,nxt,ex);
rep(i,1,m) printf("%d ",nxt[i]);
puts("");
rep(i,1,n) printf("%d ",ex[i]);
return 0;
}
扩展kmp学习笔记的更多相关文章
- 扩展kmp 学习笔记
学习了一下这个较为冷门的知识,由于从日报开始看起,还是比较绕的-- 首先定义 \(Z\) 函数表示后缀 \(i\) 与整个串的 \(lcp\) 长度 一个比较好的理解于实现方式是类似于 \(manac ...
- 126B Password[扩展kmp学习]
题目大意 给你一个字符串,求它的一个子串使得这个子串即使前缀又是后缀又出现在不是前缀且不是后缀的地方 分析 扩展kmp就是定义z[i]表示i~n的子串与整个串的最长公共前缀的长度是z[i] 所以这个题 ...
- KMP学习笔记
功能 字符串T,长度为n. 模板串P,长度为m.在字符串T中找到匹配点i,使得从i开始T[i]=P[0], T[i+1]=P[1], . . . , T[i+m-1]=P[m-1] KMP算法先用O( ...
- C#扩展方法学习笔记
C#扩展方法,简单的理解是不修改原来类的源代码的情况下,为某个类添加某个方法.扩展方法被定义为静态方法,但它们是通过实例方法语法进行调用的.它们的第一个参数指定该方法作用于哪个类型,并且该参数以 th ...
- Unity扩展编辑器学习笔记--从路径下找到拥有某个组件类型的预设
public static List<T> GetAssetsWithScript<T>(string path) where T:MonoBehaviour { T tmp; ...
- ReactiveX 学习笔记(0)学习资源
ReactiveX 学习笔记 ReactiveX 学习笔记(1) ReactiveX 学习笔记(2)创建数据流 ReactiveX 学习笔记(3)转换数据流 ReactiveX 学习笔记(4)过滤数据 ...
- Kuangbin 带你飞 KMP扩展KMP Manacher
首先是几份模版 KMP void kmp_pre(char x[],int m,int fail[]) { int i,j; j = fail[] = -; i = ; while (i < m ...
- Kotlin学习笔记(9)- 数据类
系列文章全部为本人的学习笔记,若有任何不妥之处,随时欢迎拍砖指正.如果你觉得我的文章对你有用,欢迎关注我,我们一起学习进步! Kotlin学习笔记(1)- 环境配置 Kotlin学习笔记(2)- 空安 ...
- HDU 4333 Revolving Digits [扩展KMP]【学习笔记】
题意:给一个数字,每一次把它的最后一位拿到最前面,一直那样下去,分别求形成的数字小于,等于和大于原来数的个数. SAM乱搞失败 当然要先变SS了 然后考虑每个后缀前长为n个字符,把它跟S比较就行了 如 ...
随机推荐
- Angular 学习笔记 (cdk focus monitor 和一些 focus tabindex 的基础)
更新 : 2019-12-22 focusInitialElementWhenReady 我们经常会调用到这个方法, 它的逻辑是这样 先看有没有 cdkFocusInitial 有的就 focus ...
- MyBatis Generator 自动生成的POJO对象的使用(二)
四.Example Class使用说明 示例类指定如何构建动态where子句. 表中的每个非BLOB列都可以选择包含在where子句中. 示例是演示此类用法的最佳方法. 示例类可用于生成几乎无限制的w ...
- centos 7 配置pytorch运行环境
华为云服务器,4核心8G内存,没有显卡,性能算凑合,赶上双11才不到1000,性价比还可以,打算配置一套训练densenet的环境. 首先自带的python版本是2.7,由于明年开始就不再维护了,所以 ...
- log4net SmtpAppender 踩坑总结
错误集合: System.Net.Mail.SmtpException: 命令顺序不正确. 服务器响应为:Error: need EHLO and AUTH first ! System.Net.Ma ...
- html中a标签的4个伪类样式
在CSS超链接的属性中,有四个连接方式:a:link a:hover a:visited a:acticve 之前在使用的时候一直是按照自认为的顺序中去写的,就是 L H V A的排序方式,然而有些时 ...
- git 打tag标着版本
1.git tag v1.0 2.git push origin v1.0
- java,单文件和多文件上传代码范例
上传一个单文件,用request.getFile得到文件(下面的功能是上传到阿里云) @RequestMapping(value = {"/content"}, method = ...
- Shodan全世界在线设备搜索引擎
reproduction from https://danielmiessler.com/study/shodan/ What is Shodan? Shodan is a search engine ...
- 【转载】解密ThreadLocal
概述 相信读者在网上也看了很多关于ThreadLocal的资料,很多博客都这样说:ThreadLocal为解决多线程程序的并发问题提供了一种新的思路:ThreadLocal的目的是为了解决多线程访问资 ...
- Windows Server 2008搭建单域环境
前言 一个典型的单域环境由主机,DC(Domain Controller域控制器).DNS服务器组成.DNS.DC都可以有多个,以实现负载均衡和容错 域中的计算机通过DNS解析域控制器,然后向域控制器 ...