[蓝桥杯学习] ST表

RMQ问题

ST 表

用状态 sij 记录区间长度为 2^j 的长度的区间的最大值

所以状态转移方程就是 stij = max( stij-1 , sti+(1 \<\< (j-1))j-1 )

注意状态转移的方向,保证区间合法性(i+2^j 不能超过数组大小)

写完这些后,定义好第一个,就可以从前往后进行计算

用ST表进行区间查询

ST表存储的区间是2的整数倍,所以要计算的是,如何从要求的区间,到ST表存储的区域。

要寻找一个k,如果满足以下的大小关系,

就可以取两个区间的最大值 max(stlk,str-(1\<\k),这两个区间是囊括了整个要求的区域。

k值的具体计算是,把(r-l+1)对2求对数,并向下取整,可以用强制类型转换来实现。

求区间最大值的代码

cpp 复制代码
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;

#define ll long long

const int N = 5e5 + 5;
int n,q;
ll a[N];
ll st[N][21];

ll getMax(int l,int r)
{
  //计算k,区间长度对2取对数
  int k = log(r-l+1)/log(2);
  return max(st[l][k],st[r-(1<<k)+1][k]); 
}


int main()
{
  // 请在此输入您的代码
  cin >> n >> q;
  for(int i = 1 ; i <= n ; i++)
  {
    int x;
    cin >> x;
    a[i] = x;
  }
  //构造ST表
  //1.初始化
  for(int i = 1 ; i <= n ; i++) st[i][0] = a[i];
  //2.利用状态转移方程求ST表
  for(int j = 1 ; j <= 20 ; j++)
  {
    for(int i = 1 ; i <= n ; i++)
    {
      if(i + (1<<j) -1 <= n)   //不要忘记-1,是要区间长度为 2^j 的
      {
        st[i][j] = max(st[i][j-1],st[i+(1<<(j-1))][j-1]);
      }
    }
  }
  //3.利用ST表来求区间最大值
  while(q--)
  {
    int l,r;
    cin >> l >> r;
    cout << getMax(l,r) <<'\n';
  }



  return 0;
}
相关推荐
通信小呆呆3 天前
当算法有了“五感”:多模态数据融合如何向人体感官协同学习?
人工智能·学习·算法·机器学习·机器人
H__Rick4 天前
自动对焦学习-3
人工智能·学习·计算机视觉
Daisy Lee4 天前
量化学习-第1章-什么是量化金融
学习·金融·datawhale
Alsn864 天前
等待学习-学习目录:Docker 容器安全攻防
学习·安全·docker
YM52e4 天前
买菜计算器小应用 - HarmonyOS ArkUI 开发实战-PC版本
学习·华为·harmonyos·鸿蒙·鸿蒙系统
小雨下雨的雨4 天前
HarmonyOS ArkUI训练营入门-组件掌握系列-Animation 动画效果实现-PC版本
学习·华为·harmonyos·鸿蒙
cqbzcsq4 天前
CellFlow虚拟细胞论文阅读
论文阅读·人工智能·笔记·学习·生物信息
YangYang9YangYan4 天前
2026初入职场学习数据分析的价值
学习·数据挖掘·数据分析
guslegend4 天前
理论学习:什么是 Coding Agent?
学习
自传.4 天前
尚硅谷 Vibe Coding|第三章(1) Claude Code深度使用与进阶技巧 学习笔记
笔记·学习·尚硅谷·vibecoding