ST表(算法篇)

server/2024/9/23 18:57:32/

算法篇之ST表

引言:ST表实际是一个数据结构,但是它本质是基于dp算法的,而算法题中有时也会用到,这边我就归类于算法篇先把

ST表

概念

  • ST表适用于解决区间最值的问题(RMQ问题)的数据结构
  • ST表本质是dp算法,只不过dp是对数组一排一排更新,而RMQ是对数组一列一列动态规划的
  • 预处理时间复杂度为O(nlogn)查询时间复杂度为O(1)

操作

例题:给一个数组,有n个数,有m个left,right(left和right为区间边界),求出这m个区间的最值

  1. 首先引入状态f[i][j],f[i][j]表示从第i个元素开始的长度为2j个元素的最值
  2. 将第i个元素开始的2j个元素分成长度相等的两部分,每部分的长度为2j-1
  3. 状态转移方程就为:f[i][j]=max(f[i][j-1],f[i+2j-1][j-1]),即两部分的最大值
  4. 边界条件f[i][0]=a[i]
  5. 要询问区间[L,R]的最大值,因区间[L,R]的长度为R-L+1,求出log2(R-L+1)的值,设为x
  6. 因此区间[L,R]就可以分为[L,L+2x-1]和[R-2x+1,R]两个部分,根据状态转移方程可以得出区间[L,R]的最大值RMQ(L,R)=max(f[L][x],f[R-2x+1][x])
  7. 2x可以用移位运算1<<x提高效率
int query(int l,int r){int x=(int)log(r-l+1)/log(2);    //在c++中log默认为以10为底,所以需要换底//或者直接使用log2函数int x=(int)log2(r-l+1);return max(f[l][x],f[r-(1<<x)+1][x]);
}

代码

#include <iostream>
#include <math.h>
using namespace std;
//例子
const int N=1e6+10;
int f[N][20];  //20是由log2(n)+1算出来的
int n,m;int query(int l,int r){
//    int x=(int)log(r-l+1)/log(2);int x=(int)log2(r-l+1);return max(f[l][x],f[r-(1<<x)+1][x]);
}int main() {cin>>n>>m;for(int i=1;i<=n;++i){int p;cin>>p;f[i][0]=p;}//外层循环是遍历列,列不需要遍历到n,而是2的j次方小于等于n// 因为f[i][j]代表的是从i开始的2的j次方个元素的最值,因此j最大只能取到log2(n)for(int j=1;(1<<j)<=n;++j){for(int i=1;i+(1<<j)-1<=n;++i){f[i][j]=max(f[i][j-1],f[i+(1<<(j-1))][j-1]);}}while(m--){int x,y;cin>>x>>y;cout<<query(x,y)<<endl;}system("pause");return 0;
}

例题

蓝桥杯2415:附近最小

image

#include <iostream>
#include <vector>
#include <math.h>
using namespace std;int n, k;//ST算法
int query(int l, int r, vector<vector<int>> &f) {int x = (int)log2(r - l + 1);return min(f[l][x], f[r - (1 << x) + 1][x]);
}int main() {cin >> n ;int logn = log2(n) + 1;vector<vector<int>>f(n + 1, vector<int>(logn));for (int i = 1; i <= n; ++i) {cin >> f[i][0];}for (int j = 1; (1 << j) <= n; ++j) {for (int i = 1; i + (1 << j) - 1 <= n; ++i) {f[i][j] = min(f[i][j - 1], f[i + (1 << (j - 1))][j - 1]);}}cin >> k;for (int i = 1; i <= n; ++i) {int l = max(1, i - k);int r = min(n, i + k);cout << query(l, r, f) << " ";}cout << endl;return 0;
}

http://www.ppmy.cn/server/120930.html

相关文章

(k8s)Kubernetes部署Promehteus

转载&#xff1a;Kubernetes&#xff08;k8s&#xff09;部署Promehteus 一、概述 在1.8版本以后heapster由metrics-server替代&#xff1b;从k8s的v1.11版本开始已经全面转向以Prometheus为核心的新监控体系架构&#xff1b;kube-prometheus 中包含了 prometheus 监控所用到的…

安全热点问题

安全热点问题 1.DDOS2.补丁管理3.堡垒机管理4.加密机管理 1.DDOS 分布式拒绝服务攻击&#xff0c;是指黑客通过控制由多个肉鸡或服务器组成的僵尸网络&#xff0c;向目标发送大量看似合法的请求&#xff0c;从而占用大量网络资源使网络瘫痪&#xff0c;阻止用户对网络资源的正…

Excel的基本应用 ___2

快速插入函数 方法一&#xff1a; 方法二&#xff1a;快捷键 Alt&#xff1a;求和 动态查看 利用函数清单选择函数 相对地址和绝对地址的转换 FnF4

Unity 中实现左右气泡的聊天效果

在 Unity 中实现左右气泡的聊天效果&#xff0c;通常用于消息列表或聊天框界面&#xff0c;类似于微信、WhatsApp 等聊天应用的视觉风格。这个效果可以通过 Grid Layout Group 或 Vertical Layout Group 等布局组件结合预制体来实现。 实现步骤&#xff1a; 1. 创建基本的 UI 结…

力扣2208.将数组各元素总和减半需要最少次数(贪心+堆)

题目描述 给你一个正整数数组 nums 。每一次操作中&#xff0c;你可以从 nums 中选择 任意 一个数并将它减小到 恰好 一半。&#xff08;注意&#xff0c;在后续操作中你可以对减半过的数继续执行操作&#xff09;请你返回将 nums 数组和 至少 减少一半的 最少 操作数。 示例…

自动化生成与更新 Changelog 文件

在软件开发中&#xff0c;保持 Changelog 文件的更新是一项至关重要的任务。 Changelog 文件记录了项目的每一个重要变更&#xff0c;包括新功能、修复的问题以及任何可能破坏现有功能的变更。对于维护者、贡献者和最终用户来说&#xff0c;这都是一个宝贵的资源。然而&#x…

聊聊AUTOSAR:基于Vector MICROSAR的TC8测试开发方案

技术背景 车载以太网技术作为汽车智能化和网联化的重要组成部分&#xff0c;正逐步成为现代汽车网络架构的核心&#xff0c;已广泛应用于汽车诊断&#xff08;如OBD&#xff09;、ECU软件更新、智能座舱系统、高清摄像头环视泊车系统等多个领域。 在这个过程中&#xff0c;ET…

【Android】模糊搜索与数据处理

【Android】模糊搜索与数据处理 本篇博客主要以根据输入内容动态获取城市为例进行讲解。 获取城市 这一部分主要是根据输入的信息去动态获取城市信息 首先定义了一个名为 NetUtil 的类&#xff0c;主要用于通过 HTTP 请求获取城市信息。 public class NetUtil {private stat…