当前位置: 首页 > news >正文

ST表(算法篇)

算法篇之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.mrgr.cn/news/28656.html

相关文章:

  • 【Linux】进程的概念
  • 数据结构——快速排序
  • 基于STM32的智能家居安防系统设计
  • 丹摩征文活动|FLUX.1 和 ComfyUI:从部署到上手,轻松驾驭!
  • Pixel Streaming入门教程:SignallingWebServer
  • spring框架基础
  • 音视频开发之旅(94)-多模态之Blip-2
  • 第一次安装Pytorch
  • MessagesPlaceholder
  • uniapp中实现<text>文本内容点击可复制或拨打电话
  • [性能]高速收发的TCP/MQTT通信
  • 微服务_1、入门
  • 使用卷积神经网络进行人类活动识别的特征学习:惯性测量单元和音频数据的案例研究
  • macOS Sequoia 15 发布,iPhone 镜像、密码应用程序、窗口平铺更新等带来全新体验
  • 云原生信息安全:筑牢数字化时代的安全防线
  • 107. 超快速排序
  • 系统架构设计师教程 第5章 5.7 软件项目管理 笔记
  • [Java]maven从入门到进阶
  • Linux基础---07文件传输及解决yum安装失效的方法
  • 年化60.7%,最大回撤-16.5%,RSRS标准分择时效果差不多
  • pytorch 模型训练太慢怎么办,试一试这17种方法可以优化训练过程,pytorch 提高训练速度的方法 除了num_worker
  • 【小白】一文安装anaconda
  • Java创建者模式(一)——单例设计模式(饿汉式、懒汉式、枚举式 | 完成详解,附有代码+案例)
  • docker容器镜像服务配置
  • Vue学习记录之一(介绍及脚手架的使用)
  • 深入解析 Cursor:AI 驱动的编程工具与应用示例