ExKMP Z函数

news/2025/1/22 11:19:57/文章来源:https://www.cnblogs.com/HarlemBlog/p/18685351
更新日志 20250122:开工。

思路

我们定义 \(z_i\) 表示\(i\) 开始的后缀整个字符串最长公共前缀长度

考虑它的作用,假如我们要字符串匹配,将模式串接在前面并以特殊字符分隔,然后 \(O(n)\) 遍历原串,当 \(z_i=|T|\)\(T\) 为模式串)时,这个位置就是一个匹配上的位置的开始。

然后我们考虑如何快速求出 \(z\)

我们考虑储存最大的 \(i+z_i\) 信息,称作 \(zbox\),也就是匹配上的最大右边界。比如:
image
假如这一段(右侧,左边的是与其相同部分)就是 \(zbox\)

下面我们考虑 \(i\),也就是当前需要的。

如果 \(i\) 位于 \(zbox\) 内(在 \(zbox\) 外暴力即可),那我们可以找出其在左侧的对应位置。
image

如果对应位置的 \(z\) 在对应的 \(r\) 以内(相等不算),那么显然 \(z_i=z_j\)\(j\) 为对应位置),因为下一位是相等的,上一段不行,这一段一样的不行。

不然,下一位就是不相等的,就得暴力了。但是,我们可以把 \(zbox\) 以内的部分直接 \(O(1)\) 加过来。

更新 \(zbox\) 部分就不说了,判右边界即可。

这样不难发现每个点只会被暴力一次,复杂度 \(O(n)\)

模板

string a,b;
int z[N],l,r;
void getz(string s){z[0]=l=r=0;repl(i,1,s.size()){if(i<=r&&z[i-l]<r-i+1)z[i]=z[i-l];else{z[i]=max(0,r-i+1);while(i+z[i]<s.size()&&s[i+z[i]]==s[z[i]])z[i]++;}if(i+z[i]-1>r)l=i,r=i+z[i]-1;}
}

例题

LG5410

代码
#include<bits/stdc++.h>
using namespace std;typedef long long ll;
typedef unsigned long long ull;
typedef __int128 i128;
typedef double db;
typedef long double ld;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef pair<int,ll> pil;
typedef pair<ll,int> pli;
template <typename Type>
using vec=vector<Type>;
template <typename Type>
using grheap=priority_queue<Type>;
template <typename Type>
using lrheap=priority_queue<Type,vector<Type>,greater<Type> >;
#define fir first
#define sec second
#define pub push_back
#define pob pop_back
#define puf push_front
#define pof pop_front
#define chmax(a,b) a=max(a,b)
#define chmin(a,b) a=min(a,b)
#define rep(i,x,y) for(int i=(x);i<=(y);i++)
#define repl(i,x,y) for(int i=(x);i<(y);i++)
#define per(i,x,y) for(int i=(x);i>=(y);i--)const int inf=0x3f3f3f3f;
const ll INF=0x3f3f3f3f3f3f3f3f;
const int mod=998244353;const int N=4e7+5;string a,b;
int z[N],l,r;
void getz(string s){z[0]=l=r=0;repl(i,1,s.size()){if(i<=r&&z[i-l]<r-i+1)z[i]=z[i-l];else{z[i]=max(0,r-i+1);while(i+z[i]<s.size()&&s[i+z[i]]==s[z[i]])z[i]++;}if(i+z[i]-1>r)l=i,r=i+z[i]-1;}
}ll ans1,ans2;int main(){ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);cin>>a>>b;a=b+' '+a;getz(a);z[0]=b.size();repl(i,0,b.size())ans1^=((ll)(i+1)*(z[i]+1));repl(i,b.size()+1,a.size())ans2^=((ll)(i-b.size())*(z[i]+1));cout<<ans1<<"\n"<<ans2;return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/873178.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【资产梳理】 攻击面资产梳理可视化工具

免责声明: ⽂中所涉及的技术、思路和⼯具仅供以安全为⽬的的学习交流使⽤,任何⼈不得将其⽤于⾮法⽤途以及盈利等⽬的,否则后果⾃⾏承担。所有渗透都需获取授权!确定攻击面对于防御和进攻网络安全团队都至关重要。毫无疑问,可视化映射比简单的列表更有效。专家可以快速掌握…

OpenWRT24.10旁路由挂载USB移动硬盘,配置Samba4,作为NAS使用,解决中文不显示,乱码,解决断电重启后挂载失败问题

1. 为何选择OpenWRT 24.10,及如何配置旁路由,或者IPv6地址 看这篇:参OpenWRT24.10配置作为旁路由,并配置获取IPv4和IPv6地址 使用的OpenWRT固件是从这里下载的:https://openwrt.ai/ 2.挂载大容量USB移动硬盘 2.1 安装必备插件 kmod-fs-ntfs3 kmod-fs-ext4 kmod-fs-exfat…

如何迅速并识别处理MDL锁阻塞问题

TaurusDB推出MDL锁视图功能,帮助用户迅速识别并处理MDL锁阻塞问题,从而有效减少对业务的负面影响,提升数据库管理效率。摘要:TaurusDB推出MDL锁视图功能,帮助用户迅速识别并处理MDL锁阻塞问题,从而有效减少对业务的负面影响,提升数据库管理效率。本文分享自华为云社区《…

运维职业要求

摘抄知乎@Hi峰兄运维技能导图量化自己的技能深度 级别 水平 0   啥都不懂 1   理解基本概念,应用场景 2   基本的安装,配置,使用,常用配置修改,定位基本问题 3 根据实际情况定位、优化服务,了解服务核心模块运行机制,熟悉服务的各种使用方法 4 深…

关于RNN (循环神经网络)相邻采样为什么在每次迭代之前都需要将参数detach

转自:https://www.cnblogs.com/catnofishing/p/13287322.htmldetach到底有什么作用呢 首先要明确一个意识:pytorch是动态计算图,每次backward后,本次计算图自动销毁,但是计算图中的节点都还保留。 ​ 方向传播直到叶子节点为止,否者一直传播,直到找到叶子节点 我的答案是…

网站后台上传商品功能失效,如何排查和修复?

网站后台上传商品功能失效会影响正常的业务运营,因此需要尽快排查并修复。以下是详细的排查步骤和解决方案:确认前端页面加载情况: 首先,在浏览器中打开网站后台,检查页面是否完全加载,特别是上传商品相关的JavaScript和CSS文件。如果存在资源加载失败的情况,可能是由于…

云服务器频繁出现大流量提醒及访问异常

您好,当您频繁收到关于服务器流量过大的提醒,并且站点访问出现异常(如502 Bad Gateway或504 Gateway Timeout)时,这可能是由以下几个方面的原因造成的。下面我们将详细介绍这些问题及其对应的解决方案:流量来源分析:首先,确定流量来源是否合法。使用流量分析工具(如(网…

云服务器未预装网站管理系统

您好,当您购买新的云服务器时发现未预装网站管理系统,这通常是因为不同服务商提供的初始镜像有所不同。以下是一些常见原因及其解决方案:操作系统选择:在选择操作系统时,请注意某些版本可能默认不包含网站管理助手。如果您希望获得预装的建站工具,建议选择带有集成环境的…

IDEA如何快速回到上一次编辑的地方

前言 大家好,我是小徐啊。我们在使用IDEA开发Java应用的时候,经常是需要在不同的代码文件里面来回编辑的,这个是开发的常态。 如果小伙伴们不清楚IDEA如何快捷地切换代码文件,就会极大地影响开发效率。今天,小徐就来介绍其中的一种切换方式:回到上一次编辑的地方。 如何回…

织梦网站修改后台:掌握织梦CMS的后台管理

问题描述 织梦CMS是一款流行的CMS系统,用户可以通过后台管理系统进行网站内容和模板的修改。了解如何使用织梦CMS进行后台修改是提升网站管理能力的关键。 解决方案登录后台管理使用管理员账号登录织梦CMS后台管理系统。编辑内容在“内容管理”模块中编辑或添加新的文章、产品…

关于浏览器或者调试工具阻止前端请求

1、Block request URL(拦截前端请求某个接口)2、Block request domain(拦截前端请求某个域名的所有请求)

请问PHP网站如何修改网页代码?

修改PHP网站的网页代码,需要以下步骤:访问服务器:使用FTP客户端或服务器控制面板的文件管理器,访问存储PHP网站文件的服务器。 定位文件:在服务器上找到包含要修改的网页代码的PHP文件,通常位于网站根目录下的特定文件夹中,如public_html或www。 下载文件:将PHP文件下载…