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学习笔记的更多相关文章

  1. 扩展kmp 学习笔记

    学习了一下这个较为冷门的知识,由于从日报开始看起,还是比较绕的-- 首先定义 \(Z\) 函数表示后缀 \(i\) 与整个串的 \(lcp\) 长度 一个比较好的理解于实现方式是类似于 \(manac ...

  2. 126B Password[扩展kmp学习]

    题目大意 给你一个字符串,求它的一个子串使得这个子串即使前缀又是后缀又出现在不是前缀且不是后缀的地方 分析 扩展kmp就是定义z[i]表示i~n的子串与整个串的最长公共前缀的长度是z[i] 所以这个题 ...

  3. 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( ...

  4. C#扩展方法学习笔记

    C#扩展方法,简单的理解是不修改原来类的源代码的情况下,为某个类添加某个方法.扩展方法被定义为静态方法,但它们是通过实例方法语法进行调用的.它们的第一个参数指定该方法作用于哪个类型,并且该参数以 th ...

  5. Unity扩展编辑器学习笔记--从路径下找到拥有某个组件类型的预设

    public static List<T> GetAssetsWithScript<T>(string path) where T:MonoBehaviour { T tmp; ...

  6. ReactiveX 学习笔记(0)学习资源

    ReactiveX 学习笔记 ReactiveX 学习笔记(1) ReactiveX 学习笔记(2)创建数据流 ReactiveX 学习笔记(3)转换数据流 ReactiveX 学习笔记(4)过滤数据 ...

  7. Kuangbin 带你飞 KMP扩展KMP Manacher

    首先是几份模版 KMP void kmp_pre(char x[],int m,int fail[]) { int i,j; j = fail[] = -; i = ; while (i < m ...

  8. Kotlin学习笔记(9)- 数据类

    系列文章全部为本人的学习笔记,若有任何不妥之处,随时欢迎拍砖指正.如果你觉得我的文章对你有用,欢迎关注我,我们一起学习进步! Kotlin学习笔记(1)- 环境配置 Kotlin学习笔记(2)- 空安 ...

  9. HDU 4333 Revolving Digits [扩展KMP]【学习笔记】

    题意:给一个数字,每一次把它的最后一位拿到最前面,一直那样下去,分别求形成的数字小于,等于和大于原来数的个数. SAM乱搞失败 当然要先变SS了 然后考虑每个后缀前长为n个字符,把它跟S比较就行了 如 ...

随机推荐

  1. Istio流量管理能力介绍

    1      Istio是什么? Istio 1.0版本于8月1号凌晨准点发布,核心特性已支持上生产环境,各大微信公众号.博客纷纷发文转载.那么Istio到底是什么?能解决问题什么? 1. Istio ...

  2. RMAN备份,catalog注册rman带库备份信息

    客户需求:测试恢复的过程中,控制文件是全备时期的,recover database无法恢复到指定日期,控制文件中缺失后续新的归档备份信息. 方法:1.控制文件rman注册后续带库中的归档备份: 2.使 ...

  3. shell 学习笔记7-shell-函数

    一.函数 1.什么是shell函数 把相同程序段定义成函数,可以减少整个程序的代码量,提升开发效率 增加程序的可读性,易读性,提升管理效率 可以失效程序功能模块化,使程序具备可移植性 其实linux系 ...

  4. Spring中bean的管理

    Spring 中常见的容器 我们知道spring容器就是spring中bean的驻留场所.spring容器并不是只有一个.spring自带了多个容器实现,可以归为两种不同的类型:bean工厂和应用上下 ...

  5. html中标签的英文含义!

    html中的标签缩写的英文是什么?  标签  英文全称  含义 ul unordered lists 无序列表 li list item 列表项目 ol ordered lists 有序列表 dl d ...

  6. Python中闭包的原理

    定义: 如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包(closure). 简单闭包的例子: 下面是一个使用闭包简单的例子,模拟一个计数器,通过将 ...

  7. iOS 动画基础-显式动画

    摘要 显式动画 属性动画 CABasicAnimation *animation = [CABasicAnimation animation];         [self updateHandsAn ...

  8. requests模块的基本用法

    requests 什么是requests模块 python中封装好的一个基于网络请求的模块 作用 用来模拟浏览器发送请求 环境安装 pip install requests 编码流程 指定 url 发 ...

  9. 前端编译原理 parser.js源码解读

    前面已经介绍了一个jison的使用,在正常开发中其实已经够用下,下面主要是看了下parser.js代码解读下,作为一些了解. 下面以最简单的文法产生的parser做一些代码注释 下面是一些注释,标示了 ...

  10. django_rest framework 接口开发(一)

    1 restful 规范(建议) 基于FbV def order(request): if request.method=="GET": return HttpResponse(' ...