(C++) 稀疏表Sparse Table

news2024/10/6 2:22:23

目录

一、介绍

       1.1 倍增 

        1.2 稀疏表ST

二、原理

三、代码实现

3.1 创建稀疏表

3.2 初始化数值

3.3 ST查询


一、介绍

       1.1 倍增 

        倍增的思想是在数据空间特别大的时候,快速进行查找搜索而使用的。例如想要在一个数据量为n的递增数组中查找到等于x的下标,最简单想到的就是遍历整个数组。而现在以2^{i}步长进行搜索,若x小于该节点,则加大增量2^{i+1}继续比较;否则减小增量2^{i-1}继续比较,知道搜索到目标节点。

        1.2 稀疏表ST

        稀疏表采用了倍增的思想,在O(nlogn)时间构造了一个二维表之后,在O(1)时间在线查询[l ,r]区间的最值,有效解决区间最值问题。这是一种不支持在线修改,对静态数据进行搜索的算法。

        简单来说,稀疏表就是,对于一个区间,想要快速找到其中的最大值(最小值),于是就划分为多个区间,按照一定的步长找到对应每一个小模块的最大值后映射到一个二维表中,这样下一次查找最值的时候,就能按照规定的规律直接进行检索。

二、原理

        定义F[i,j] 表示区间[i, i + 2^{j}- 1]的最值,其中 i 为该区间的起始点,j为搜索步长,区间长度为2^{j} 。

        递推公式:F[i,j] = max(F[i,j-1],F[i+2^{j-1},j-1])

将区间划分为两个子区间后求解迭代最值。如果是创建最小值,则对公式稍微进行修改:

F[i,j] = min(F[i,j-1],F[i+2^{j-1},j-1])

        第一个区间为[i,i+2^{j-1}-1],所以第二个区间是从i+2^{j-1}开始的,这里稍微做一下解释

三、代码实现

3.1 创建稀疏表

std::vector<std::vector<int>> sparseTable;

3.2 初始化数值

函数输入需要放入稀疏表中的数组

稀疏表的第一列是数组排入,从第二列开始映射数据。

例如:[7,2,3,0,5,8,4,6]为输入数据,则

数据量n = 8;最大检索量logn = 4

创建的稀疏表为

void createSparseTable(const std::vector<int>& nums)
{
	int n = nums.size();		//数据量
	int logn = log2(n) + 1;		//稀疏表的列数,算是最大检索量
	sparseTable.resize(n, std::vector<int>(logn));
	/*
	*稀疏表是将所有的元素都按列进行排放,横向填充
	*/
	//填充第一列		
	for (int i = 0; i < n; i++)
	{
		sparseTable[i][0] = nums[i];
	}
	//递推公式: F[i,j]=max(F[i,j-1],F[i+2^(j-1)][j-1])
	//填充其余列
	for (int j = 1; j < logn; j++)
	{
		for (int i = 0; i + (1 << j) <= n; i++)
		{
			sparseTable[i][j] = std::max(sparseTable[i][j - 1], sparseTable[i + (1 << (j - 1))][j - 1]);
		}
	}
}

3.3 ST查询

l,r分别为区间的左端点和右端点

//查询区间最值
int query(int l, int r)
{
	int len = r - l + 1;
	int k = log2(len);		//查询步长
	return std::max(sparseTable[l][k], sparseTable[r - (1 << k) + 1][k]);		//时间复杂度为O(1)的查询
}

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

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

相关文章

算法|基础算法|高精度算法

基础算法|位运算 1.高精度加法 2.高精度减法 3.高精度乘法 4.高精度除法 心有猛虎&#xff0c;细嗅蔷薇。你好朋友&#xff0c;这里是锅巴的C\C学习笔记&#xff0c;常言道&#xff0c;不积跬步无以至千里&#xff0c;希望有朝一日我们积累的滴水可以击穿顽石。 高精度加法 …

图灵奖得主AviWigderson:随机性与AI深度融合,引领计算科学新篇章

近日&#xff0c;理论计算机科学领域的杰出代表Avi Wigderson教授荣获了享有“计算机界诺贝尔奖”美誉的图灵奖&#xff0c;以表彰他对计算中随机性和伪随机性研究的杰出贡献。这一荣誉不仅彰显了Wigderson教授在计算理论领域的卓越成就&#xff0c;也为当前热门的AI和深度学习…

打破常规,重新定义PMP备考之路

今天我想和大家聊聊一个我们都不陌生的话题——PMP备考。你是不是也在备考的苦海中挣扎&#xff0c;或是听说过各种“速成”的神话&#xff1f;&#x1f914; 最近读到一篇文章&#xff08;来着圣略PMP培训讲师老杨&#xff09;&#xff0c;让我对PMP备考有了新的认识。原来&a…

如何用flutter写一个好的登录页面

编写一个好的登录页面是构建用户友好且安全的移动应用的重要一步。下面是使用Flutter编写一个好的登录页面的一些建议和步骤&#xff1a; 1. 设计用户界面 1.简洁明了的布局&#xff1a;确保界面简洁明了&#xff0c;不要过分复杂&#xff0c;避免用户感到困惑。 2.清晰的输入框…

1、IPEX-LLM(原名BigDL-LLM)环境配置

IPEX-LLM 是一个为Intel XPU (包括CPU和GPU) 打造的轻量级大语言模型加速库&#xff0c;在Intel平台上具有广泛的模型支持、最低的延迟和最小的内存占用。 您可以使用 IPEX-LLM 运行任何 PyTorch 模型&#xff08;例如 HuggingFace transformers 模型&#xff09;。在运行过程中…

Redis的IO模型 和 多线程问题

Redis中的线程和IO模型 什么是Reactor模式 &#xff1f;单线程Reactor模式流程单线程Reactor&#xff0c;工作者线程池多Reactor线程模式 Redis中的线程和IO概述socketI/O多路复用程序文件事件分派器文件事件处理器文件事件的类型总结 多线程问题1. Redis6.0之前的版本真的是单…

05节-51单片机-模块化编程

1.两种编程方式的对比 传统方式编程&#xff1a; 所有的函数均放在main.c里&#xff0c;若使用的模块比较多&#xff0c;则一个文件内会有很多的代码&#xff0c;不利于代码的组织和管理&#xff0c;而且很影响编程者的思路 模块化编程&#xff1a; 把各个模块的代码放在不同的…

学习java时候的笔记(十六)

常用API Math 是一个帮助我们用于进行数学计算的工具类 Math中常用的方法 方法名说明abs(int a)获取参数的绝对值abs(-1) > 1ceil(double b)向上取整1.1 > 2floor(double b)向下取整1.7>1round(float a)四舍五入max(int a, int b)取两个整数的最大值max(2,3) >…

LeetCode-924. 尽量减少恶意软件的传播【深度优先搜索 广度优先搜索 并查集 图 哈希表】

LeetCode-924. 尽量减少恶意软件的传播【深度优先搜索 广度优先搜索 并查集 图 哈希表】 题目描述&#xff1a;解题思路一&#xff1a;解题思路二&#xff1a;0解题思路三&#xff1a;0 题目描述&#xff1a; 给出了一个由 n 个节点组成的网络&#xff0c;用 n n 个邻接矩阵图…

02_对象树

#include "mypushbutton.h" #include <QDebug>MyPushButton::MyPushButton(QWidget *parent): QPushButton(parent) {qDebug()<<"我的按钮类构造调用"; }MyPushButton::~MyPushButton() {qDebug()<<"我的按钮类析构调用"; }交…

「JavaEE」线程

&#x1f387;个人主页&#xff1a;Ice_Sugar_7 &#x1f387;所属专栏&#xff1a;JavaEE &#x1f387;欢迎点赞收藏加关注哦&#xff01; 线程 &#x1f349;线程&#x1f34c;多线程&#x1f34c;线程与进程的联系&区别&#x1f34c;多线程编程&#x1f34c;创建线程&a…

spring02:DI(依赖注入)

spring02&#xff1a;DI&#xff08;依赖注入&#xff09; 文章目录 spring02&#xff1a;DI&#xff08;依赖注入&#xff09;前言&#xff1a;一、构造器注入&#xff08;constructor&#xff09;二、set注入&#xff1a;分析&#xff1a; 1. Student类&#xff1a;2. Addres…

【大语言模型】轻松本地部署Stable Diffusion

硬件要求&#xff1a; 配备至少8GB VRAM的GPU&#xff0c;如果你的电脑只有CPU&#xff0c;请看到最后。根据部署规模&#xff0c;需要足够的CPU和RAM。 软件要求&#xff1a; Python 3.7或更高版本。支持NVIDIA GPU的PyTorch。Hugging Face的Diffusers库。Hugging Face的Tr…

什么是神经网络和机器学习?【云驻共创】

什么是神经网络和机器学习&#xff1f; 一.背景 在当今数字化浪潮中&#xff0c;神经网络和机器学习已成为科技领域的中流砥柱。它们作为人工智能的支柱&#xff0c;推动了自动化、智能化和数据驱动决策的进步。然而&#xff0c;对于初学者和专业人士来说&#xff0c;理解神经…

WordPress 告别 MySQL:Docker SQLite WordPress

本篇文章聊聊&#xff0c;如何将这个持续诞生和维护了 21 年的开源软件“脱离数据库”运行&#xff0c;让它能够更加轻量、适合低成本离线运行。 写在前面 2003 年&#xff0c;Michel Valdrighi 基于 b2/cafelog 创建了开源软件 WordPress&#xff0c;并在 GPL 协议下发布。 …

【Java EE】关于Spring MVC 响应

文章目录 &#x1f38d;返回静态页面&#x1f332;RestController 与 Controller 的关联和区别&#x1f334;返回数据 ResponseBody&#x1f38b;返回HTML代码片段&#x1f343;返回JSON&#x1f340;设置状态码&#x1f384;设置Header&#x1f338;设置Content-Type&#x1f…

012Node.js自定义模块文件名不是index.js引入的方法

nodejs默认会找node_modules对应模块db里的index.js //var dbrequire(db) //错误&#xff0c;因为nodejs默认会找node_modules对应模块db里的index.jsvar dbrequire(db); //没有错误&#xff0c;是因为在DB目录的CMD下执行了npm init --yes&#xff0c;生成了package.json文…

【VIC水文模型】模型输入/输出参数简介

VIC水文模型输入参数简介 输入数据1.1 背景参数1.2 植被分类及属性配置1.3 土壤数据库制作1.4 气象数据库制作1.5 区域控制文件1.6 汇流文件制作 输出数据参考 VIC水文模型是基于空间分布网格化的分布式水文模型。通过将研究区域网格化&#xff0c;分别考虑每个计算网格内裸土和…

单片机之ESP8266模块

目录 ESP8266简介 前言 ESP8266的工作模式 ESP8266引脚说明 ESP8266测试 步骤 单片机与esp8266交互 前言 收到数据的格式 AP模式 服务器模式 外部执行命令 代码内执行命令 代码部分 客户端模式 外部执行命令 内部执行命令 代码部分 STA模式 服务器模式 外…

Springboot+Vue项目-基于Java+MySQL的企业客户管理系统(附源码+演示视频+LW)

大家好&#xff01;我是程序猿老A&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f49e;当前专栏&#xff1a;Java毕业设计 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f380; Python毕业设计 &…