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

例题:https://acm.sdut.edu.cn/onlinejudge3/problems/4928ui​​​​​​

第一种方式:

这一种做法就和正常的字符串哈希基本思想一样,都是h[r]=h[l-1]*p[r-l+1];

我们这里是左高右低,故是hash[ l ]=hash[ l ]*p[ r.len ]+hash[ r ];

且注意要query要先递归右子树,以便于先维护出右部分的len

#include <bits/stdc++.h>
using namespace std;
#define pi acos(-1)
#define xx first
#define yy second
#define endl "\n"
#define lowbit(x) x & (-x)
#define int long long
#define ull unsigned long long
#define pb push_back
typedef pair<int, int> PII;
typedef pair<double, double> PDD;
#define max(a, b) (((a) > (b)) ? (a) : (b))
#define min(a, b) (((a) < (b)) ? (a) : (b))
#define Ysanqian ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
const int N = 1e6 + 10, M = 1010, inf = 0x3f3f3f3f, mod = 998244353, P = 13331;
const double eps = 1e-8;
char s[N];
int n, q;
int p[N];
struct node
{int l, r;int len;int hash1, hash2;
} tr[N << 2];
void init()
{p[0] = 1;for (int i = 1; i <= n + 10; i++)p[i] = p[i - 1] * P;
}
void pushup(node &u, node &l, node &r)
{u.hash1 = l.hash1 * p[r.len] + r.hash1;u.hash2 = r.hash2 * p[l.len] + l.hash2;
}
void pushup(int u)
{pushup(tr[u], tr[u << 1], tr[u << 1 | 1]);
}
void build(int u, int l, int r)
{tr[u] = {l, r, r - l + 1, 0, 0};if (l == r){tr[u] = {l, r, 1, (int)s[l], (int)s[l]};return;}int mid = l + r >> 1;build(u << 1, l, mid);build(u << 1 | 1, mid + 1, r);pushup(u);
}
void modify(int u, int x, int k)
{if (tr[u].l == x && tr[u].r == x){tr[u].hash1 = k;tr[u].hash2 = k;return;}int mid = tr[u].l + tr[u].r >> 1;if (x <= mid)modify(u << 1, x, k);elsemodify(u << 1 | 1, x, k);pushup(u);
}
int query1(int u, int l, int r, int &len1)
{if (tr[u].l >= l && tr[u].r <= r){int temp = (tr[u].hash1 * p[len1]) % mod;len1 += tr[u].len;return temp;}else{int res = 0;int mid = tr[u].l + tr[u].r >> 1;if (r > mid)res += query1(u << 1 | 1, l, r, len1);if (l <= mid)res += query1(u << 1, l, r, len1);return res % mod;}
}
int query2(int u, int l, int r, int &len2)
{if (tr[u].l >= l && tr[u].r <= r){int temp = (tr[u].hash2 * p[len2]) % mod;len2 += tr[u].len;return temp;}int res = 0;int mid = tr[u].l + tr[u].r >> 1;if (l <= mid)res += query2(u << 1, l, r, len2);if (r > mid)res += query2(u << 1 | 1, l, r, len2);return res % mod;
}
void solve()
{cin >> n >> q;cin >> (s + 1);init();build(1, 1, n);while (q--){int op;cin >> op;if (op == 2){int l, r;cin >> l >> r;int len1 = 0, len2 = 0;int x = query1(1, l, r, len1);int y = query2(1, l, r, len2);if (x == y)cout << "Yes" << endl;elsecout << "No" << endl;}else{int x;char k;cin >> x >> k;modify(1, x, (int)k);}}
}
signed main()
{Ysanqian;int T;T = 1;// cin >> T;while (T--)solve();return 0;
}

第二种方式:

这一种直接暴力维护的正反哈希,一个左高右低,一个右高左低,相比较于第一种做法多了一个快速幂的log( 注意取mod,不然会wa)

#include <bits/stdc++.h>
using namespace std;
#define pi acos(-1)
#define xx first
#define yy second
#define endl "\n"
#define lowbit(x) x & (-x)
#define int long long
#define ull unsigned long long
#define pb push_back
typedef pair<int, int> PII;
typedef pair<double, double> PDD;
#define max(a, b) (((a) > (b)) ? (a) : (b))
#define min(a, b) (((a) < (b)) ? (a) : (b))
#define Ysanqian ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
const int N = 1e6 + 10, M = 1010, inf = 0x3f3f3f3f, mod = 1e9 + 7, P = 13331;
const double eps = 1e-8;
char s[N];
int n, q;
int p[N];
struct node
{int l, r;int len;int hash1, hash2;
} tr[N << 2];
void init()
{p[0] = 1;for (int i = 1; i <= n; i++)p[i] = p[i - 1] * P % mod;
}
int qpow(int a, int b)
{int res = 1;while (b){if (b & 1)res = res * a % mod;a = a * a % mod;b >>= 1;}return res;
}
void pushup(node &u, node &l, node &r)
{u.hash1 = (l.hash1 + r.hash1) % mod;u.hash2 = (l.hash2 + r.hash2) % mod;
}
void pushup(int u)
{pushup(tr[u], tr[u << 1], tr[u << 1 | 1]);
}
void build(int u, int l, int r)
{tr[u] = {l, r, r - l + 1, 0, 0};if (l == r){tr[u] = {l, r, 1, (int)s[l] * p[n - l], (int)s[r] * p[r - 1]};return;}int mid = l + r >> 1;build(u << 1, l, mid);build(u << 1 | 1, mid + 1, r);pushup(u);
}
void modify(int u, int x, int k)
{if (tr[u].l == x && tr[u].r == x){tr[u].hash1 = k * p[n - x] % mod;tr[u].hash2 = k * p[x - 1] % mod;return;}int mid = tr[u].l + tr[u].r >> 1;if (x <= mid)modify(u << 1, x, k);elsemodify(u << 1 | 1, x, k);pushup(u);
}
int query1(int u, int l, int r)
{if (tr[u].l >= l && tr[u].r <= r)return tr[u].hash1;else{int res = 0;int mid = tr[u].l + tr[u].r >> 1;if (r > mid)res += query1(u << 1 | 1, l, r);if (l <= mid)res += query1(u << 1, l, r);return res % mod;}
}
int query2(int u, int l, int r)
{if (tr[u].l >= l && tr[u].r <= r)return tr[u].hash2;int res = 0;int mid = tr[u].l + tr[u].r >> 1;if (l <= mid)res += query2(u << 1, l, r);if (r > mid)res += query2(u << 1 | 1, l, r);return res % mod;
}
void solve()
{cin >> n >> q;cin >> (s + 1);init();build(1, 1, n);while (q--){int op;cin >> op;if (op == 2){int l, r;cin >> l >> r;int x = query1(1, l, r);int y = query2(1, l, r);x = (x * qpow(p[n - r], mod - 2)) % mod;y = (y * qpow(p[l - 1], mod - 2)) % mod;// cout << x << ' ' << y << endl;if (x == y)cout << "Yes" << endl;elsecout << "No" << endl;}else{int x;char k;cin >> x >> k;modify(1, x, (int)k);}}
}
signed main()
{Ysanqian;int T;T = 1;// cin >> T;while (T--)solve();return 0;
}

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

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

相关文章

第9步---MySQL的索引和存储引擎

第9步---MySQL的索引和存储引擎 1.索引 1.1分类 索引可以快速的找出具有特定值的行。不用从头开始进行寻找了。 类别 hash和btree hash 根据字段值生生成一个hash的值 快速的进行定位到对应的行的值 可能会出现相同的值&#xff0c;找到对应的空间会出现对应的值 btree树…

LTMC S/4HANA 2022 – 迁移您的数据

翻译一篇&#xff0c;估计很少人用过这个LTMC功能&#xff0c;更不用说&#xff0c;LTMOM了。一个还没开始用已经被弃用的事务代码&#xff1a; 在这篇博文中&#xff0c;我将解释如何在 S/4HANA 2022 版本中通过“迁移您的数据”应用程序逐步执行数据迁移。如您所知&#xff0…

5.7.webrtc线程的启动与运行

那在上一节课中呢&#xff1f;我向你介绍了web rtc的三大线程&#xff0c;包括了信令线程&#xff0c;工作线程以及网络线程。那同时呢&#xff0c;我们知道了web rtc 3大线程创建的位置以及运行的时机。 对吧&#xff0c;那么今天呢&#xff1f;我们再继续深入了解一下&#…

Redis分布式缓存

分布式缓存 -- 基于Redis集群解决单机Redis存在的问题 单机的Redis存在四大问题&#xff1a; 1.Redis持久化 Redis有两种持久化方案&#xff1a; RDB持久化 AOF持久化 1.1.RDB持久化 RDB全称Redis Database Backup file&#xff08;Redis数据备份文件&#xff09;&#x…

Certify The Web (IIS)

一、简介 Certify The Web 适用于 Windows的SSL 证书管理器用户界面&#xff0c;与所有 ACME v2 CA 兼容&#xff0c;为您的 IIS/Windows 服务器轻松地安装和自动更新来自 Letencrypt.org 和其他 ACME 证书授权机构的免费 SSL/TLS 证书&#xff0c;设置 https 从未如此简单。 …

【实用工具】磁盘被写保护怎么解除

磁盘被写保护怎么解除 我的是磁盘3无法写只能读&#xff0c;具体的执行步骤看下面 C:\Users\wsw>diskpartMicrosoft DiskPart 版本 10.0.19041.964Copyright (C) Microsoft Corporation. 在计算机上: SH-DB751B3DISKPART> list disk磁盘 ### 状态 大小 可…

JSON的处理

1、JSON JSON(JavaScript Object Notation)&#xff1a;是一种轻量级的数据交换格式。 它是基于 ECMAScript 规范的一个子集&#xff0c;采用完全独立于编程语言的文本格式来存储和表示数据。 简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。易于人阅读和编写&#…

保研之旅1:西北工业大学电子信息学院夏令营

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; 本人持续分享更多关于电子通信专业内容以及嵌入式和单片机的知识&#xff0c;如果大家喜欢&#xff0c;别忘点个赞加个关注哦&#xff0c;让我们一起共同进步~ &#x…

[PyTorch][chapter 49][创建自己的数据集 1]

前言&#xff1a; 后面几章主要利用DataSet 创建自己的数据集&#xff0c;实现建模&#xff0c; 训练&#xff0c;迁移等功能。 目录: pokemon 数据集深度学习工程步骤 一 pokemon 数据集介绍 1.1 pokemon: 数据集地址&#xff1a; 百度网盘路径: https://pan.baidu.com/s/1…

二、8.系统调用、可变参数和堆内存管理

系统调用&#xff1a;让用户进程申请操作系统的帮助 一个系统功能调用分为两部分&#xff0c; 一部分是暴露给用户进程的接口函数&#xff0c;它属于用户空间&#xff0c;此部分只是用户进程使用系统调用的途径&#xff0c;只负责发需求。另一部分是与之对应的内核具体实现&am…

C++day1(笔记整理)

一、Xmind整理&#xff1a; 二、上课笔记整理&#xff1a; 1.第一个c程序&#xff1a;hello world #include <iostream> //#:预处理标识符 //<iostream>:输入输出流类所在的头文件 //istream:输入流类 //ostream:输出流类using namespace std; //std&#x…

Goland 注释时自动在注释符号后添加空格

不得不说 JetBrains 旗下的 IDE 都好用&#xff0c;而且对于注释这块&#xff0c;使用 Ctrl / 进行注释的时候&#xff0c;大多会在每个注释符号后统一添加一个空格&#xff0c;比如 PyCharm 和 RubeMine 等。 # PyCharm # print("hello world") # RubyMine # req…

从Web 2.0到Web 3.0,互联网有哪些变革?

文章目录 Web 2.0时代&#xff1a;用户参与和社交互动Web 3.0时代&#xff1a;语义化和智能化影响和展望 &#x1f389;欢迎来到Java学习路线专栏~从Web 2.0到Web 3.0&#xff0c;互联网有哪些变革&#xff1f; ☆* o(≧▽≦)o *☆嗨~我是IT陈寒&#x1f379;✨博客主页&#x…

Python入门教程 | Python 基础语法

标识符 第一个字符必须是字母表中字母或下划线 _ 。标识符的其他的部分由字母、数字和下划线组成。标识符对大小写敏感。 在 Python 3中&#xff0c;可以用中文作为变量名&#xff0c;非 ASCII 标识符也是允许的了。默认情况下&#xff0c;Python 3 源码文件以 UTF-8 编码&am…

易思智能物流无人值守系统文件上传漏洞复现

0x01 产品简介 易思无人值守智能物流系统是一款集成了人工智能、机器人技术和物联网技术的创新产品。它能够自主完成货物存储、检索、分拣、装载以及配送等物流作业&#xff0c;帮助企业实现无人值守的智能物流运营&#xff0c;提高效率、降低成本&#xff0c;为现代物流行业带…

Unity 物体固定屏幕尺寸(透视模式)

物体固定屏幕尺寸 &#x1f96a;效果图&#x1f371;食用方法 &#x1f96a;效果图 如图所示物体远离摄像机后会被放大&#xff0c;靠近相机会被缩小&#xff0c;使得在屏幕上的大小保持不变&#xff1b; &#x1f371;食用方法 导入插件后使用gameObject.SetFixedScreenSi…

python 开发环境(PyCharm)搭建指南

Python 的下载并安装 参考&#xff1a;Python基础教程——搭建Python编程环境 下载 Python Python 下载地址&#xff1a;官网 &#xff08;1&#xff09;点击【Downloads】>>>点击【Windows】>>>点击【Python 3.x.x】下载最新版 Python&#xff1b; Pyt…

前端(十三)——JavaScript 闭包的奥秘与高级用法探索

&#x1f636;博主&#xff1a;小猫娃来啦 &#x1f636;文章核心&#xff1a;深入理解 JavaScript 中的闭包 文章目录 不理解闭包&#xff1f;这玩意很难&#xff1f;闭包的定义与原理闭包是什么创建一个闭包 闭包的应用场景闭包与作用域闭包与作用域之间的关系全局作用域、函…

Python爬虫实战案例——第一例

X卢小说登录(包括验证码处理) 地址&#xff1a;aHR0cHM6Ly91LmZhbG9vLmNvbS9yZWdpc3QvbG9naW4uYXNweA 打开页面直接进行分析 任意输入用户名密码及验证码之后可以看到抓到的包中传输的数据明显需要的是txtPwd进行加密分析。按ctrlshiftf进行搜索。 定位来到源代码中断点进行调…

ES6 代理

一、代理 Proxy 用于修改某些操作的默认行为&#xff0c;等同于在语言层面做出修改&#xff0c;所以属于一种“元编程”&#xff08;meta programming&#xff09;&#xff0c;即对编程语言进行编程。 Proxy 可以理解成&#xff0c;在目标对象之前架设一层“拦截”&#xff0…