KMP 算法求解字符串匹配的过程中 \(next\) 数组有着繁多的应用,主要是可以帮我们求 border。

然而用 \(s\) 串匹配 \(t\) 串产生的 \(f\) 数组应用相对较少。

\(f\) 数组的实际意义就是与当前考虑的 \(t\) 串前缀的某个后缀相同的长度最大的 \(s\) 串前缀。所有与 \(t\) 串该前缀的后缀匹配的 \(s\) 串前缀可以通过这个前缀跳 border 得来。

那么我们回忆 LCP 的暴力求法:从两个起始位置 \(i,j\) 暴力匹配,找到第一个 \(k\) 满足 \(s_{i+k}\neq s_{j+k}\),\(k\) 就是答案。

现在如果对于一个跟当前串 \(t[1,i]\) 后缀匹配的 \(s\) 串前缀 \(j\) 满足 \(s_{j+1}\neq t_{i+1}\),那么显然有 \(z_{i-j+1}=j\)。

暴力跳所有的匹配的 \(s\) 串前缀复杂度肯定无法接受,但我们发现我们只需要找到所有 \(s_{j+1}\neq t_{i+1}\) 的匹配前缀即可。而由于每个位置的 LCP 只会在它失配的位置处计算一次,所以如果能快速找到这些前缀均摊下来就是 \(O(n)\) 的。

具体地,跟动态 border 的维护方式很类似,我们只需要在 \(nxt\) 树上预处理跳父亲跳到的第一个后继字符不同的位置。这个预处理可以边求 \(nxt\) 边做,只需要一遍循环就搞定了。代码还是比较好写的。

#include <cstdio>
#include <cstring>
using namespace std;
const int N=20000003;
typedef long long ll;
char t[N],s[N];
int n,m;
int nxt[N],f[N],z[N],w[N];
int main(){
scanf("%s",t+1);m=strlen(t+1);
scanf("%s",s+1);n=strlen(s+1);s[n+1]='#';
for(int i=2,j=0;i<=n;++i){
while(j&&s[j+1]!=s[i]) j=nxt[j];
if(s[j+1]==s[i]) ++j;
nxt[i]=j;
if(s[i+1]==s[j+1]) f[i]=f[j];
else f[i]=j;
int p=j;
while(p){
if(s[p+1]!=s[i+1]) z[i-p+1]=p,p=nxt[p];
else p=f[p];
}
}
z[1]=n;
for(int i=1,j=0;i<=m;++i){
while(j&&s[j+1]!=t[i]) j=nxt[j];
if(s[j+1]==t[i]) ++j;
int p=j;
while(p){
if(s[p+1]!=t[i+1]) w[i-p+1]=p,p=nxt[p];
else p=f[p];
}
}
ll valz=0,valw=0;
for(int i=1;i<=n;++i) valz^=(ll)i*(z[i]+1);
for(int i=1;i<=m;++i) valw^=(ll)i*(w[i]+1);
printf("%lld\n%lld\n",valz,valw);
return 0;
}

如何用 KMP 偏序 Z 函数的更多相关文章

  1. KMP 与 Z 函数

    \(\text{By DaiRuiChen007}\) 一.KMP 算法 I. 问题描述 在文本串 \(S\) 中找到模式串 \(T\) 的所有出现,其中 \(|S|=n,|T|=m\) II. 前置 ...

  2. 题解-洛谷P5410 【模板】扩展 KMP(Z 函数)

    题面 洛谷P5410 [模板]扩展 KMP(Z 函数) 给定两个字符串 \(a,b\),要求出两个数组:\(b\) 的 \(z\) 函数数组 \(z\).\(b\) 与 \(a\) 的每一个后缀的 L ...

  3. luogu P5410 模板 扩展 KMP Z函数 模板

    LINK:P5410 模板 扩展 KMP Z 函数 画了10min学习了一下. 不算很难 思想就是利用前面的最长匹配来更新后面的东西. 复杂度是线性的 如果不要求线性可能直接上SA更舒服一点? 不管了 ...

  4. KMP&Z函数详解

    KMP 一些简单的定义: 真前缀:不是整个字符串的前缀 真后缀:不是整个字符串的后缀 当然不可能这么简单的,来个重要的定义 前缀函数: 给定一个长度为\(n\)的字符串\(s\),其 \(前缀函数\) ...

  5. 前缀函数与Z函数介绍

    字符串算法果然玄学=_= 参考资料: OI Wiki:前缀函数与KMP算法 OI Wiki:Z函数(扩展KMP) 0. 约定 字符串的下标从 \(0\) 开始.\(|s|\) 表示字符串 \(s\) ...

  6. exkmp(Z函数) 笔记

    exkmp 用于求解这样的问题: 求文本串 \(T\) 的每一个后缀与模式串 \(M\) 的匹配长度(即最长公共前缀长度).特别的,取 \(M=T\),得到的这个长度被称为 \(Z\) 函数.&quo ...

  7. Atcoder Regular Contest 058 D - 文字列大好きいろはちゃん / Iroha Loves Strings(单调栈+Z 函数)

    洛谷题面传送门 & Atcoder 题面传送门 神仙题. mol 一发现场(bushi)独立切掉此题的 ycx %%%%%%% 首先咱们可以想到一个非常 naive 的 DP,\(dp_{i, ...

  8. Z 函数

    简单记一下,避免忘记. z 函数 对于字符串 \(S\),我们将 \(z(i)\) 定义为从 \(i\) 开始的后缀与 \(S\) 的最长公共前缀的长度. \(O(n)\) 求出 z 函数 我们添加一 ...

  9. KMP算法-next函数求解

    KMP函数求解:一种改进的字符串匹配算法,由D.E.Knuth,J.H.Morris和V.R.Pratt同时发现,因此人们称它为KMP算法.KMP算法的关键是利用匹配失败后的信息,尽量减少模式串与主串 ...

  10. 自动化测试(三)如何用python写一个函数,这个函数的功能是,传入一个数字,产生N条邮箱,产生的邮箱不能重复。

    写一个函数,这个函数的功能是,传入一个数字,产生N条邮箱,产生的邮箱不能重复.邮箱前面的长度是6-12之间,产生的邮箱必须包含大写字母.小写字母.数字和特殊字符 和上一期一样 代码中间有段比较混沌 有 ...

随机推荐

  1. Asp.net MVC5中没有BundleConfig.cs-MVC学习笔记(一)

    创建ASP.NET MVC5项目时,选择了空项目,在App_Start文件夹中没有默认创建了BudleConfig.cs文件. 下面就来手动添加 在NuGet中搜索Microsoft.AspNet.W ...

  2. K8S—dashboard ui部署

    一.Dashboard UI概述 仪表板是基于Web的Kubernetes用户界面.您可以使用仪表板将容器化应用程序部署到Kubernetes集群,对容器化应用程序进行故障排除,并管理集群本身及其伴随 ...

  3. Sitecore 应用与介绍

    前言 因为工作需要,开始了 sitecore 之旅,在使用之中碰到了许多问题,后续开始写一下关于 sitecore 的文章. sitecore 官网:https://www.sitecore.com/ ...

  4. node使用multer进行文件上传

    开场白 在平时的业务中,我们很多使用都会有文件上传这个功能. 今天分享一下使用 node+element-ui实现一下文件上传. 请个人大佬指点一番~~~.批评的时候稍微轻一点. 毕竟我心里承受能力弱 ...

  5. 《程序员的自我修养》学习笔记——ELF 文件结构介绍【第二弹】

    ELF 文件结构介绍 文件头 以 ELF 文件64位版本为例: e_ident [ELF魔数 16byte] 1-4字节:ELF 文件都必须相同的标识码,分别为 0x7F,0x45,0x4C,0x46 ...

  6. D3和X6

    D3 版本 d3已经更新到v7版本,中文文档只更新到v4版本,存在部分api不适用和过时问题 使用d3-darge插件布局,插件适配d3版本为v5,近年未更新 API 使用darge中setNode和 ...

  7. 中高等DP总结(更新中

    1.CF613D Kingdom and its Cities 题意:给定一棵树,每个询问给出一些关键点,要求删掉最少的点使这些点两两不联通,无解输出-1. 思路:先判无解:只要有一个关键点的父亲也是 ...

  8. 【LeetCode贪心#12】图解监控二叉树(正宗hard题,涉及贪心分析、二叉树遍历以及状态转移)

    监控二叉树 力扣题目链接(opens new window) 给定一个二叉树,我们在树的节点上安装摄像头. 节点上的每个摄影头都可以监视其父对象.自身及其直接子对象. 计算监控树的所有节点所需的最小摄 ...

  9. 大数据面试——Flink

    一.公司怎么提交的实时任务,有多少 Job Manager.TaskManager 是多少 我们使用 yarn session 模式提交任务:另一种方式是每次提交都会创建一个新的 Flink集群,为每 ...

  10. Cisco模拟器配置DNS服务器遇到的问题

    1.使用工具: Cisco-Packet-Tracer(7.0或8.0版本及以上) 2.问题: 原因:安装思科模拟器后进行中文汉化: 过程:配置DNS服务时无法进行域名操作: 解决: 更改为原来的语言 ...