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. java第一次笔试+面试总结

    今天是自己第一次java笔试和面试,总体感觉比预期好一点. 笔试题第一面是问答题,主要考查java基础,一共有18题,我有6道题没有写出来.第二面主要是算法题,一共有8道题,我大概写出来4道题,第三面 ...

  2. Java 面向对象_接口

    接口定义 接口就是多个类的公共规范 接口是一种引用数据类型, 最重要的内容是其中的抽象方法 定义格式: public interface MyInterfaceAbstract { // 这是一个抽象 ...

  3. 前端之:传统的DOM是如何渲染的?

    a.纯后端渲染:页面发送请求,后端服务器中将数据拼成完整DOM树,并转换成一个字节流作为HTTP Response的body返回给浏览器.优点在于 返回的HTTP Response是包含着全部页面内容 ...

  4. Mac下多版本JDK安装及管理

    在Java项目中,经常对JDK版本有不同的要求,可是不可能为了某个项目的运行重新下载不同版本JDK进行安装,这样就涉及到对本地环境中多个JDK版本的管理. Mac的JDK都是安装到一个指定目录的:/L ...

  5. WebService 规范

    详见:https://blog.csdn.net/u011165335/article/details/51345224 JAVA 中共有三种WebService 规范,分别是JAX-WS(JAX-R ...

  6. [#Linux] CentOS 7 禁用笔记本的触摸板

    安装 xorg-x11-apps yum install xorg-x11-apps 查看对应设备的 id xinput –list 关闭 touchpad xinput set-int-prop 1 ...

  7. MySql 8.0服务端安装后,用navicat12连接时报2059错误_解决

    先看连接错误 连接失败:2059 - Authentication plugin 'caching_sha2_password' cannot be loaded: .... 解决方法: 进入MySQ ...

  8. javascript之位置

    1.offset()获取匹配元素在相对浏览器窗口的偏移量 返回一个对象,包括两个属性.left:相对浏览器窗口左边的距离.top:相对浏览器顶部的距离.  $("#div1").o ...

  9. Google hacking 语法

    a b c 自动对词进行拆分匹配 拆分标准 空格 "a b c " 把a b c 当成一个整体去查 " a*b" *通配符 里面是一个或者多个 以a开头 b结尾 ...

  10. 面向对象中特殊方法的补充、isinstance/issubclass/type、方法和函数、反射

    一.面向对象中特殊方法的补充 1.__str__ 能将对象名改成你想要的字符串,但是类型还是类 class Foo(object): def __init__(self): pass def func ...