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

ST表(稀疏表)

对ST表进行一个简单的总结,它可以实现O(1)的静态区间查询,可以适用于查询操作频繁但数据不修改的场景

题目来源

https://www.luogu.com.cn/problem/P3865

题目介绍

给定一个长度为 N 的数列,和 M 次询问,求出每一次询问的区间内数字的最大值。

解题思路

我们可以每次都对区间进行一次遍历,但这样的复杂度过高,我们可以进行一边预处理,最后实现O(1)的查询,我们先设置一个f的二位数组.

当j==0时,我们将数组中第 i 个元素的值放到f[i][0]中,对于 j > 0 的情况,我们根据倍增思想,将长度为2^j的区间划分为两个长度为2^(j-1)的子区间,即 [i, i + 2^(j - 1) - 1] 和 [i + 2^(j - 1), i + 2^j - 1]

因此,f[i][j]可以通过max(st[i][j - 1], st[i + (1 << (j - 1))][j - 1]) 得到。

对于查询,我们可以设置一个p=log2(r-l+1),然后我们可以在[l,l+2^p-1]和[r-2^p+1,r]两个区间内找到我们所需要值,对其求最大即可。

解题代码

#include<iostream>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<cstring>
#include<math.h>
using namespace std;
typedef long long ll;
const int N = 1e5 + 5;
ll f[N][30];
void ST(int xx) {for (int i = 1; i <= xx; i++) {cin >> f[i][0];}for (int i = 1; i <= 20; i++) {for (int j = 1; j + (1 << i) - 1 <= xx; j++) {f[j][i] = max(f[j][i - 1], f[j + (1 << (i - 1))][i - 1]);}}
}
ll check(int l,int r) {ll p = log2(r - l + 1);return max(f[l][p], f[r - (1 << p) + 1][p]);
}
void slove() {int n, q;cin >> n >> q;ST(n);while (q--) {ll x, y;cin >> x >> y;cout << check(x, y) << "\n";}
}
int main() {ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);int ttt = 1;while (ttt--) {slove();}
}

与此同时,我们也可以求最小值,只需修改中间一段的代码

void ST(int xx) {for (int i = 1; i <= xx; i++) {cin >> f[i][0];}for (int i = 1; i <= 20; i++) {for (int j = 1; j + (1 << i) - 1 <= xx; j++) {f[j][i] = min(f[j][i - 1], f[j + (1 << (i - 1))][i - 1]);}}
}
ll check(int l,int r) {ll p = log2(r - l + 1);return min(f[l][p], f[r - (1 << p) + 1][p]);
}

总结

这题就是这样的,主要运用了倍增和预处理的思想。

                                                                                                                                     --撰稿人viture

相关文章:

  • Unity基础学习(十一)核心系统---光源系统基础
  • 机器人运动控制原理浅析-UC Berkeley超视觉模态模型
  • 【Python 算法零基础 2.模拟 ⑤ 基于栈和队列】
  • 【递归、搜索与回溯算法】导论
  • java加强 -List集合
  • 应急响应基础模拟靶机-security2
  • 御网杯2025 Web,Msic,密码 WP
  • 深入解析多选字段的存储与查询:从位运算到数据库设计的最佳实践
  • uni-app学习笔记(二)--vue页面代码的构成和新建页面
  • html body 设置heigth 100%,body内元素设置margin-top出滚动条(margin 重叠问题)
  • [学习]RTKLib详解:convkml.c、convrnx.c与geoid.c
  • 二、transformers基础组件之Tokenizer
  • 智能座舱开发工程师面试题
  • vue中理解MVVM
  • Ubuntu 22虚拟机【网络故障】快速解决指南
  • Qt坐标系 + 信号和槽 + connect函数(8)
  • LangChain入门(七) 提取和输出结构化数据
  • AI Agent(10):个人助手应用
  • 19、DeepSeek LLM论文笔记
  • ActiveMQ 生产环境问题排查与调优指南(一)
  • 特朗普访中东绕行以色列,专家:凸显美以利益分歧扩大
  • 中国人民抗日战争暨世界反法西斯战争胜利80周年纪念活动标识发布
  • 国家统计局今年将在全国开展两次人口固定样本跟访调查
  • 专访|西蒙·斯特朗格:以“辞典”的方式讲述二战家族史
  • 湖北石首市委副书记、市长付勇接受审查调查
  • 巴西总统卢拉昨晚抵达北京