字符串哈希线段树维护字符串哈希

news/2024/9/18 16:24:59/文章来源:https://www.cnblogs.com/SkyNet-PKN/p/18414948

本文哈希数组均为 1-index,原始字符串均为 0-index。

哈希值类

typedef unsigned long long ull;
ull bs=13131,bspw[MAXN];inline void init_bspw(){bspw[0]=1;for(int i=1;i<MAXN;i++)bspw[i]=bspw[i-1]*bs;
}struct HashNode{ull val;int len;HashNode(){}HashNode(ull a,int b):val(a),len(b){}
};
inline HashNode operator + (const HashNode& a,const HashNode& b){HashNode res;res.val=a.val*bspw[b.len]+b.val;res.len=a.len+b.len;return res;
}
inline HashNode operator - (const HashNode& a,const HashNode& b){//b is prefix of aHashNode res;res.val=a.val-b.val*bspw[a.len-b.len];res.len=a.len-b.len;return res;
}
inline bool operator == (const HashNode& a,const HashNode& b){return (a.len==b.len) && (a.val==b.val);
}

静态字符串哈希

class HashString{
private:HashNode hs[MAXN];
public:inline void build(const string& str){int len=str.size();hs[0]=HashNode(0,0);for(int i=1;i<=len;i++)hs[i]=HashNode(str[i-1]-'a'+1,1);for(int i=1;i<=len;i++)hs[i]=hs[i-1]+hs[i];}inline HashNode query(const int& l,const int& r) const{return hs[r]-hs[l-1];}
};

动态字符串哈希(线段树维护字符串哈希)

\(O(\log n)\) 单点修改,\(O(\log n)\) 区间查询。

通常不会有区间直接修改的需求,因为这样输入复杂度就出问题了(

#define getmid int mid=(l+r)/2
#define lch (pos<<1)
#define rch (pos<<1|1)class HashSegTree{
private:HashNode t[MAXN<<2];inline void pushup(int pos){t[pos]=t[lch]+t[rch];}
public:void build(int pos,int l,int r,const string& str){if(l==r){t[pos]=HashNode(str[l-1]-'a'+1,1);return;}getmid;build(lch,l,mid,str);build(rch,mid+1,r,str);pushup(pos);}void update(int pos,int l,int r,int aim,char ch){if(l==r){t[pos]=HashNode(ch-'a'+1,1);return;}getmid;if(aim<=mid) update(lch,l,mid,aim,ch);else update(rch,mid+1,r,aim,ch);pushup(pos);}HashNode query(int pos,int l,int r,int ll,int rr){if(ll<=l && r<=rr){return t[pos];}getmid;HashNode res(0,0);if(ll<=mid) res=res+query(lch,l,mid,ll,rr);if(mid<rr) res=res+query(rch,mid+1,r,ll,rr);return res;}
};

线段树维护正反串哈希

仍然是 \(O(\log n)\) 单点修改,\(O(\log n)\) 区间查询。

通常用于查询字符串的某个子串是不是回文串。

模板题

#include<bits/stdc++.h>
#define getmid int mid=(l+r)/2
#define lch (pos<<1)
#define rch (pos<<1|1)
using namespace std;
typedef unsigned long long ull;
const int MAXN=1e6+5;
ull bs=13131,bspw[MAXN];struct TwinHashNode{ull fwd,bwd;int len;TwinHashNode(){}TwinHashNode(ull a,ull b,int c):fwd(a),bwd(b),len(c){}
};
inline TwinHashNode operator + (const TwinHashNode& a,const TwinHashNode& b){TwinHashNode res;res.fwd=a.fwd*bspw[b.len]+b.fwd;res.bwd=b.bwd*bspw[a.len]+a.bwd;res.len=a.len+b.len;return res;
}class HashSegTree{
private:TwinHashNode t[MAXN<<2];inline void pushup(int pos){t[pos]=t[lch]+t[rch];}
public:void build(int pos,int l,int r,const string& str){if(l==r){t[pos]=TwinHashNode(str[l-1]-'a'+1,str[l-1]-'a'+1,1);return;}getmid;build(lch,l,mid,str);build(rch,mid+1,r,str);pushup(pos);}void update(int pos,int l,int r,int aim,char ch){if(l==r){t[pos]=TwinHashNode(ch-'a'+1,ch-'a'+1,1);return;}getmid;if(aim<=mid) update(lch,l,mid,aim,ch);else update(rch,mid+1,r,aim,ch);pushup(pos);}TwinHashNode query(int pos,int l,int r,int ll,int rr){if(ll<=l && r<=rr){return t[pos];}getmid;TwinHashNode res(0,0,0);if(ll<=mid) res=res+query(lch,l,mid,ll,rr);if(mid<rr) res=res+query(rch,mid+1,r,ll,rr);return res;}
}text;int n,q;
string str;int main(){ios::sync_with_stdio(false);cin>>n>>q>>str;n=str.size();bspw[0]=1;for(int i=1;i<=n;i++)bspw[i]=bspw[i-1]*bs;text.build(1,1,n,str);int opt,l,r,x;char c;while(q--){cin>>opt;if(opt==1){cin>>x>>c;text.update(1,1,n,x,c);}else{cin>>l>>r;auto res=text.query(1,1,n,l,r);cout<<(res.fwd==res.bwd?"Yes":"No")<<endl;}}return 0;
}

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

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

相关文章

Cisco Modeling Labs (CML) 2.7.2 发布下载,新增功能概览

Cisco Modeling Labs (CML) 2.7.2 发布下载,新增功能概览Cisco Modeling Labs (CML) 2.7.2 - 网络仿真工具 思科建模实验室 (CML) 请访问原文链接:https://sysin.org/blog/cisco-modeling-labs-2/,查看最新版。原创作品,转载请保留出处。 作者主页:sysin.orgCisco Modelin…

读构建可扩展分布式系统:方法与实践04应用服务

应用服务1. 应用服务 1.1. 任何系统的核心都在于实现应用需求的特定业务逻辑 1.2. 服务是可扩展软件系统的核心1.2.1. 它们将契约定义为一个API,向客户端声明它们的能力1.3. 应用服务器高度依赖于编程语言,但通常都会提供多线程编程模型,允许服务同时处理许多请求 1.4. 多服…

【极速下载】Vmware17.5.2官方最新版本2024网盘下载

Mware简介VMware 是一款强大的虚拟化软件。它能在一台物理机上同时运行多个操作系统,实现资源高效利用。可用于服务器虚拟化、桌面虚拟化等。提高系统可靠性、可扩展性与安全性,降低成本和管理复杂度。VMware广泛应用于企业数据中心和云计算领域,是 IT 重要工具。 VMware最…

Junior.Crypt.2024 CTF - Forensics

补充学习了有关evtx以及注册表的知识Junior.Crypt.2024 CTF - Forensics 部分题目复现参考: https://blog.jacki.cn/2024/07/05/Junior_Crypt_2024_CTF/#SAMBO-wrestler https://yocchin.hatenablog.com/entry/2024/07/08/124230 标注“#”表示未复现,日后有机会补上吧 题目地…

全网最适合入门的面向对象编程教程:49 Python函数方法与接口-函数与方法的区别和lamda匿名函数

在 Python 中,函数和方法都是代码的基本单元,用于封装和执行特定的任务。它们之间有一些重要的区别,而 lambda 匿名函数则是 Python 提供的一种简洁定义小型函数的方法。全网最适合入门的面向对象编程教程:49 Python 函数方法与接口-函数与方法的区别和 lamda 匿名函数摘要…

基于 CrewAI 多智能体框架,手把手构建一个自动化写作应用实战

利用 CrewAI 多智能体框架,我们可以更细粒度的控制智能体和任务,通过不同的流程组织协同多智能体共同完成工作……明月皓皓,星河灿烂,中秋佳节,团圆美满。祝大家中秋节快乐!听说台风要来了,也不知道还能不能吃着月饼赏个月?老牛同学在上文(Agent(智能体)和 MetaGPT,一…

【推荐 - 源码安装】nginx - 安装

准备查看操作系统的版本信息[root@lab10 ~]# cat /etc/redhat-release CentOS Linux release 7.9.2009 (Core)查看操作系统的网卡地址[root@lab10 ~]# ip address show ens32 2: ens32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group de…

痞子衡嵌入式:JLink命令行以及JFlash对于下载算法的作用地址范围认定

大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家分享的是JLink命令行以及JFlash对于下载算法的作用地址范围认定。最近痞子衡在给一个 RT1170 客户定制一个 Infineon MirrorBit 类型 64MB Flash 的 SEGGER 下载算法,做完之后在 JFlash 下测试小数据下载没有问题,但…

软件工程导论——个人项目之论文查重

软件工程导论——个人项目之论文查重这个作业属于哪个课程 https://edu.cnblogs.com/campus/gdgy/CSGrade22-12/这个作业要求在哪里 https://edu.cnblogs.com/campus/gdgy/CSGrade22-12/homework/13220这个作业的目标 设计一个论文查重算法并实现;学会 Git 版本控制Github仓库…