P3865 ST表

news/2025/2/19 17:00:01/

题意

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

对于 100 % 100\% 100% 的数据,满足 1 ≤ N ≤ 10 5 1\le N\le {10}^5 1N105 1 ≤ M ≤ 2 × 10 6 1\le M\le 2\times{10}^6 1M2×106 a i ∈ [ 0 , 10 9 ] a_i\in[0,{10}^9] ai[0,109] 1 ≤ l i ≤ r i ≤ N 1\le l_i\le r_i\le N 1liriN

思路

什么是ST表

ST表,是一种用来处理**RMQ(区间最值问题)**的算法。ST表可以做到 O ( n log ⁡ n ) \mathcal{O}(n\log{n}) O(nlogn) 预处理,之后 O ( 1 ) \mathcal{O}(1) O(1) 查询, ST表的空间复杂度也是 O ( n log ⁡ n ) \mathcal{O}(n\log{n}) O(nlogn) 的。

如何实现ST表和它的原理

预处理

我们定义 S T i , j ST_{i,j} STi,j,为从第 i i i 个位置开始之后的 2 j 2^j 2j 个位置的区间最大值。 我们知道: 2 k = 2 k − 1 + 2 k − 1 2^k=2^{k-1}+2^{k-1} 2k=2k1+2k1,所以在预处理时也一样。ST表有些类似于dp的思想。 S T i , j = max ⁡ ( S T i , j − 1 , S T i + 2 j − 1 , j − 1 ) ST_{i,j}=\max(ST_{i,j-1},ST_{i+2^{j-1},j-1}) STi,j=max(STi,j1,STi+2j1,j1)

i , i + 1 , i + 2 , ⋯ , i + 2 j − 1 − 1 ⏟ max里的第一部分 , i + 2 j − 1 , i + 2 j − 1 + 1 , ⋯ , i + 2 j − 1 + 2 j − 1 − 1 ⏟ max里的第二部分 \underbrace{i,i+1,i+2,\cdots,i+2^{j-1}-1}_{\text{max里的第一部分}}\underbrace{,i+2^{j-1},i+2^{j-1}+1,\cdots,i+2^{j-1}+2^{j-1}-1}_{\text{max里的第二部分}} max里的第一部分 i,i+1,i+2,,i+2j11max里的第二部分 ,i+2j1,i+2j1+1,,i+2j1+2j11

这样就可以从小合大了。

查询

查询的话也很简单,求一下 k = log ⁡ ( r − l + 1 ) k= \log{(r-l+1)} k=log(rl+1),也就是区间长度的覆盖。然后因为向下取整,不可以直接 S T l , k ST_{l,k} STl,k,而是要用 r − 2 k + 1 r-2^k+1 r2k+1 重叠上去。不明白 r − 2 k + 1 r-2^k+1 r2k+1的话就是从终点开始往中心走那么多格子,这样的话一定可以和 S T l , k ST_{l,k} STl,k 接上。

tips

需要注意一些边界,预处理的时候不要少处理,空间也要预留够。

代码

#include<cstdio>
#include <set>
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
typedef long long ll;
const ll MAXN=1e5+5;
ll st[MAXN][40];
ll query(ll l,ll r){ll k= ll(log2(r-l+1));return max(st[l][k],st[r-(1<<k)+1][k]);
}
ll n,m,l,r;
int main(){cin>>n>>m;for (int i = 1; i <=n ; ++i) {scanf("%lld",&st[i][0]);}for (int k = 1; k <=log2(MAXN) ; ++k) {for (int i = 1; i+(1<<k)-1<=n ; ++i) {st[i][k]= max(st[i][k-1],st[i+(1<<(k-1))][k-1]);}}for (int i = 1; i <=m ; ++i) {scanf("%lld%lld",&l,&r);printf("%lld\n", query(l,r));}return 0;
}

http://www.ppmy.cn/news/281107.html

相关文章

2、DSP TMS320F28335介绍

目录 2.1 F28335封装信息 2.2 F28335内核主要特点 2.3 TMS320F28335处理器主要资源 2.4 与DSP2812的性能对比 2.5 F28335的引脚分布及其引脚功能 2.6 怎样学好F28335 2.1 F28335封装信息 F28335芯片型号&#xff1a; 2.2 F28335内核主要特点 ①F28335 DSP集成了DSP和微…

希捷ST31000528AS Disk Boot Failure, Insert System Disk and Press Enter和飞利浦的193ei显示器亮的问题

新入手的希捷1TB的硬盘。380 7200.12.1TB的希捷ST31000528AS 同时装了我的wd的500G做为硬盘。 技嘉的770t-ud3p的主板&#xff0c;识别了segeat的硬盘为主硬盘。 ---------------------------- 想装win 7 &#xff0c;没有盘&#xff0c;打算先用深度的xp系统盘格式化分区。…

一文教你选择文件服务器

一文教你选择文件服务器 仅从服务器下载&#xff0c;不上传 apache/httpd apache是linux下常用的web服务器&#xff0c;可以使用yum、apt等工具直接安装&#xff0c;其一般用于生产环境或者大规模场景。 miniserve rust写的简单的http文件服务器&#xff0c;简单轻量易用&…

【基础知识】一文看懂深度优先算法和广度优先算法

概览 先上个图 现在我们要访问图中的每个节点&#xff0c;即图的遍历。 图的遍历是指&#xff0c;从给定图中任意指定的顶点&#xff08;称为初始点&#xff09;出发&#xff0c;按照某种搜索方法沿着图的边访问图中的所有顶点&#xff0c;使每个顶点仅被访问一次&#xff…

#tmux# #终端# 常用工具tmux

tmux tmux是一个终端复用工具&#xff0c;允许用户在一个终端会话中同时管理多个终端窗口&#xff0c;提高了终端使用效率&#xff0c;尤其在服务器上进行远程管理时更加实用。在tmux中&#xff0c;可以创建多个终端窗口和窗格&#xff0c;并在这些窗口和窗格之间自由切换&…

esp32-cam图片上传巴法云,http协议传输post

1、ESP32-cam开发环境配置 本例程 是利用arduino IDE开发,关于arduino IDE 的esp32环境配置可参考:环境配置: 点击跳转 安装好esp32 环境,开发板选择esp32 wrover module开发板,其他默认即可。 2 、程序下载 示例程序下载:点击下载 需要修改的信息有WIF名称,WIFI密码,…

Linux文件理解和系统调用

本文已收录至《Linux知识与编程》专栏&#xff01; 作者&#xff1a;ARMCSKGT 演示环境&#xff1a;CentOS 7 文件理解和系统调用 前言正文文件概念文件描述符文件描述符概念文件管理关于 files_struct文件描述符的分配一切皆文件思想 C语言文件操作文件的打开与关闭文件读写 文…

买笔记本,第一是质量

苹果是买系统送电脑&#xff0c;如果你刷了win系统&#xff0c;那还不如戴尔。 中商情报网讯&#xff1a;据最新数据统计显示&#xff0c;2018年1-8月全国网络零售额为55195亿元&#xff0c;同比增长28.2%&#xff1b;其中&#xff0c;实物商品网络零售额为41993亿元&#xff0…