区间最值问题-RQM(ST表,线段树)

1.ST表求解

ST表的实质其实是动态规划,下面是区间最小的递归公式,最大只需将min改成max即可

f[i][j] = min(f[i][j - 1], f[i + (1 << j - 1)][j - 1]);

二维数组的f[i][j]表示从i开始连续2*j个数的最小/大值。

例如:我们给出一个数组a[10]={0,1,2,4,6,7,9,2,12,3};

我们可以给f[i][0]....f[n][0]先初始化为上面数组的值,我们将f[i][j]分为两端,一段是i到i+2^(j-1)-1为一段,i+2^(j-1)到i+2^j-1,f[i][j]就是分出来的这两个段的最大/小值。

于是有了递归公式。

写一道例题

P1816 忠诚 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<set>
#include<map>
#include<unordered_map>
#include<string>
#include<queue>
#include<vector>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdio>
#define TEST1 int T;cin>>T;while(T--)
#define TEST2 int T;T=1;while(T--)
#define lowbit(x) x&(-x) 
#define ll long long
using namespace std;
const int N = 100010;
const int M = 20;
int base1 = 131, base2 = 13311;
int p1 = 1e9 + 7, p2 = 1e9 + 9;
const ll mod = 1e9 + 7;
int n, a[N], f[N][M],m[N][M];
//创建ST表
void create() {//初始状态//f[i][0]表示从i开始长度为2^0的区间最值为a[i]本身for(int i = 1; i <= n; i ++) f[i][0] = a[i],m[i][0]=a[i];int k = log2(n);//枚举区间长度指数jfor(int j = 1; j <= k; 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]);m[i][j] = min(m[i][j - 1], m[i + (1 << j - 1)][j - 1]);}}
//利用ST表查询区间[L,R]的最大值
int query1(int L, int R) {int k = log2(R - L + 1);return max(f[L][k], f[R - (1 << k) + 1][k]);
}
int query2(int L,int R)
{int k=log2(R-L+1);return min(m[L][k], m[R - (1 << k) + 1][k]);
}
int main()
{int m;cin >> n >> m;for(int i = 1; i <= n; i ++) scanf("%d", a + i);create();while(m --) {int L, R;scanf("%d%d", &L, &R);printf("%d ", query2(L,R));}
}

其实就是区间最小值。

2.线段树

线段树其实也就是相当于区间分段,(a,b)的左孩子区间就是(a,(a+b)/2)和右孩子((a+b)/2+1,b),(a.b)区间的最值就是他分出的两个区间的最值的最值。

对于上道例题的代码:

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<set>
#include<map>
#include<unordered_map>
#include<string>
#include<queue>
#include<vector>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdio>
#define TEST1 int T;cin>>T;while(T--)
#define TEST2 int T;T=1;while(T--)
#define lowbit(x) x&(-x) 
#define ll long long
using namespace std;
const int N = 2000010;
const int M = 1e9+2;
int base1 = 131, base2 = 13311;
int p1 = 1e9 + 7, p2 = 1e9 + 9;
const ll mod = 1e9 + 7;
ll n, m, a[N];
struct Node
{int l, r, minn = mod;
}tree[N];
void build(int i, int l, int r)
{tree[i] = { l,r };if (l == r){tree[i].minn = a[l];return;}int mid = l + r >> 1;build(i << 1, l, mid);build(i << 1 | 1, mid + 1, r);tree[i].minn = min(tree[i << 1].minn, tree[i << 1 | 1].minn);
}
int ask(int i, int l, int r)
{if (l == tree[i].l && r == tree[i].r) return tree[i].minn;int mid = tree[i].l + tree[i].r >> 1;if (r <= mid) return ask(i << 1, l, r);if (l > mid) return ask(i << 1 | 1, l, r);return min(ask(i << 1, l, mid), ask(i << 1 | 1, mid + 1, r));
}
void solve()
{cin >> n >> m;for (int i = 1; i <= n; i++) cin >> a[i];build(1, 1, n);for (int i = 1; i <= m; i++){int l, r;cin >> l >> r;cout << ask(1, l, r) << " ";}
}
int main()
{TEST2solve();return 0;
}

3.其他例题

1.奶牛排队

1274. 奶牛排队 - AcWing题库

区间最大值与最小值的差

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<set>
#include<map>
#include<unordered_map>
#include<string>
#include<queue>
#include<vector>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdio>
#define TEST1 int T;cin>>T;while(T--)
#define TEST2 int T;T=1;while(T--)
#define lowbit(x) x&(-x) 
#define ll long long
using namespace std;
const int N = 100010;
const int M = 20;
int base1 = 131, base2 = 13311;
int p1 = 1e9 + 7, p2 = 1e9 + 9;
const ll mod = 1e9 + 7;
int n, a[N], f[N][M],m[N][M];
//创建ST表
void create() {//初始状态//f[i][0]表示从i开始长度为2^0的区间最值为a[i]本身for(int i = 1; i <= n; i ++) f[i][0] = a[i],m[i][0]=a[i];int k = log2(n);//枚举区间长度指数jfor(int j = 1; j <= k; 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]);m[i][j] = min(m[i][j - 1], m[i + (1 << j - 1)][j - 1]);}}
//利用ST表查询区间[L,R]的最大值
int query1(int L, int R) {int k = log2(R - L + 1);return max(f[L][k], f[R - (1 << k) + 1][k]);
}
int query2(int L,int R)
{int k=log2(R-L+1);return min(m[L][k], m[R - (1 << k) + 1][k]);
}
int main()
{int m;cin >> n >> m;for(int i = 1; i <= n; i ++) scanf("%d", a + i);create();while(m --) {int L, R;scanf("%d%d", &L, &R);printf("%d\n", query1(L,R)-query2(L,R));}
}

2.求m区间内的最小值

P1440 求m区间内的最小值 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<set>
#include<map>
#include<unordered_map>
#include<string>
#include<queue>
#include<vector>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdio>
#define TEST1 int T;cin>>T;while(T--)
#define TEST2 int T;T=1;while(T--)
#define lowbit(x) x&(-x) 
#define ll long long
using namespace std;
const int N = 2000010;
const int M = 1e9 + 2;
int base1 = 131, base2 = 13311;
int p1 = 1e9 + 7, p2 = 1e9 + 9;
const ll mod = 1e9 + 7;
ll n, m, a[N];
struct Node
{ll l, r, minn = mod;
}tree[N];
void build(int i, int l, int r)
{tree[i] = { l,r };if (l == r){tree[i].minn = a[l];return;}int mid = l + r >> 1;build(i << 1, l, mid);build(i << 1 | 1, mid + 1, r);tree[i].minn = min(tree[i << 1].minn, tree[i << 1 | 1].minn);
}
int ask(int i, int l, int r)
{if (l == tree[i].l && r == tree[i].r) return tree[i].minn;int mid = tree[i].l + tree[i].r >> 1;if (r <= mid) return ask(i << 1, l, r);if (l > mid) return ask(i << 1 | 1, l, r);return min(ask(i << 1, l, mid), ask(i << 1 | 1, mid + 1, r));
}
void solve()
{cin >> n >> m;for (int i = 1; i <= n; i++) cin >> a[i];build(1, 1, n);for (int i = 1; i <= n; i++){if (i == 1){cout << "0\n";continue;}int l=max(1ll,i-m), r=i-1;cout << ask(1, l, r) << "\n";}
}
int main()
{TEST2solve();return 0;
}

用单调队列更简单。。。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/41515.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

uniapp启动安卓模拟器mumu

mumu模拟器下载 ADB&#xff1a; android debug bridge &#xff0c; 安卓调试桥&#xff0c;是一个多功能的命令行工具&#xff0c;他使你能够与连接的安卓设备进行交互 # adb连接安卓模拟器 adb connect 127.0.0.1:port # 查看adb设备 adb deviceshubuilderx 有内置的adb&a…

MSPM0G3507——滴答定时器和普通定时

滴答定时器定时&#xff1a;&#xff08;放在主函数即可&#xff09; volatile unsigned int delay_times 0;//搭配滴答定时器实现的精确ms延时 void delay_ms(unsigned int ms) {delay_times ms;while( delay_times ! 0 ); } //滴答定时器中断 void SysTick_Handler(…

Python28-7.4 独立成分分析ICA分离混合音频

独立成分分析&#xff08;Independent Component Analysis&#xff0c;ICA&#xff09;是一种统计与计算技术&#xff0c;主要用于信号分离&#xff0c;即从多种混合信号中提取出独立的信号源。ICA在处理盲源分离&#xff08;Blind Source Separation&#xff0c;BSS&#xff0…

【机器学习】(基础篇一) —— 什么是机器学习

什么是机器学习 本系列博客为你从机器学习的介绍开始&#xff0c;使用大量的代码实战和验证&#xff0c;最终帮助你完全掌握什么是机器学习 人工智能、机器学习和深度学习的关系 人工智能&#xff08;Artificial Intelligence&#xff0c;AI&#xff09;&#xff1a;是一门研…

Java多线程不会?一文解决——

方法一 新建类如MyThread继承Thread类重写run()方法再通过new MyThread类来新建线程通过start方法启动新线程 案例&#xff1a; class MyThread extends Thread {public MyThread(String name) {super(name);}Overridepublic void run() {for(int i0;i<10;i){System.out.…

react dangerouslySetInnerHTML将html字符串以变量方式插入页面,点击后出现编辑状态

1.插入变量 出现以下编辑状态 2.解决 给展示富文本的标签添加css样式 pointerEvents: none

那些年背过的面试题——MySQL篇

本文是技术人面试系列 MySQL 篇&#xff0c;面试中关于 MySQL 都需要了解哪些基础&#xff1f;一文带你详细了解&#xff0c;欢迎收藏&#xff01; WhyMysql&#xff1f; NoSQL 数据库四大家族 列存储 Hbase K-V 存储 Redis 图像存储 Neo4j 文档存储 MongoDB 云存储 OSS …

AI大模型的智能心脏:向量数据库的崛起

在人工智能的飞速发展中,一个关键技术正悄然成为AI大模型的智能心脏——向量数据库。它不仅是数据存储和管理的革命性工具,更是AI技术突破的核心。随着AI大模型在各个领域的广泛应用,向量数据库的重要性日益凸显。 01 技术突破:向量数据库的内在力量 向量数据库以其快速检索…

RNN、LSTM与GRU循环神经网络的深度探索与实战

循环神经网络RNN、LSTM、GRU 一、引言1.1 序列数据的迷宫探索者&#xff1a;循环神经网络&#xff08;RNN&#xff09;概览1.2 深度探索的阶梯&#xff1a;LSTM与GRU的崛起1.3 撰写本博客的目的与意义 二、循环神经网络&#xff08;RNN&#xff09;基础2.1 定义与原理2.1.1 RNN…

【Python】组合数据类型:序列,列表,元组,字典,集合

个人主页&#xff1a;【&#x1f60a;个人主页】 系列专栏&#xff1a;【❤️Python】 文章目录 前言组合数据类型序列类型序列常见的操作符列表列表操作len()append()insert()remove()index()sort()reverse()count() 元组三种序列类型的区别 集合类型四种操作符集合setfrozens…

【CSS in Depth 2精译】2.5 无单位的数值与行高

当前内容所在位置 第一章 层叠、优先级与继承第二章 相对单位 2.1 相对单位的威力2.2 em 与 rem2.3 告别像素思维2.4 视口的相对单位2.5 无单位的数值与行高 ✔️2.6 自定义属性2.7 本章小结 2.5 无单位的数值与行高 有些属性允许使用无单位的数值&#xff08;unitless value…

【数据结构与算法】快速排序挖坑法

&#x1f493; 博客主页&#xff1a;倔强的石头的CSDN主页 &#x1f4dd;Gitee主页&#xff1a;倔强的石头的gitee主页 ⏩ 文章专栏&#xff1a;《数据结构与算法》 期待您的关注 ​

前端面试题16(跨域问题)

跨域问题源于浏览器的同源策略&#xff08;Same-origin policy&#xff09;&#xff0c;这一策略限制了来自不同源的“写”操作&#xff08;比如更新、删除数据等&#xff09;&#xff0c;同时也限制了读操作。当一个网页尝试请求与自身来源不同的资源时&#xff0c;浏览器会阻…

Python实现ABC人工蜂群优化算法优化随机森林回归模型(RandomForestRegressor算法)项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档视频讲解&#xff09;&#xff0c;如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 人工蜂群算法(Artificial Bee Colony, ABC)是由Karaboga于2005年提出的一种新颖的基于群智能的全局优化…

PD虚拟机不能复制Mac的文件怎么回事 PD虚拟机不能复制Mac的文件怎么办 Parallels Desktop怎么用

PD虚拟机不仅能提供跨系统协作的服务&#xff0c;还能进行虚拟机系统与原生系统间的文件共享、文本复制、文件复制等操作&#xff0c;让系统间的资源可以科学利用。但在实际操作过程中&#xff0c;PD虚拟机不能复制Mac的文件怎么回事&#xff1f;PD虚拟机不能复制Mac的文件怎么…

linux centos7.9 安装mysql5.7;root设置客户端登录、配置并发、表名大小写敏感等

查看centos版本 cat /etc/centos-releasecentos版本为7.9 查看是否已安装mariadb,安装了需要先删除 1.查看是否安装了mariadb和mysql,安装了需要先删除 mariadb是mysql的一个分支,但要安装mysql需要删除它 执行rpm -qa|grep mariadb,查看mariadb情况 查找到有就删除 执行…

Day59 动态规划part12

LC115不同的子序列&#xff08;未掌握&#xff09; 递推公式与LC392类似&#xff0c;但是初始化略有不同 LC392的dp数组含义为相同字符个数而本体的dp数组含义为出现的次数&#xff0c;因此dp[i][0]1 两种情况 s[i-1]t[j-1] dp[i][j] dp[i-1][j-1]dp[i][j] dp[i-1][j] s[…

Kubernetes集群性能测试之kubemark集群搭建

Kubernetes集群性能测试之kubemark集群搭建 Kubemark是K8s官方提供的一个对K8s集群进行性能测试的工具。它可以模拟出一个K8s cluster&#xff08;Kubemark cluster&#xff09;&#xff0c;不受资源限制&#xff0c;从而能够测试的集群规模比真实集群大的多。这个cluster中ma…

运维锅总详解系统启动流程

本文详细介绍Linux及Windows系统启动流程&#xff0c;并分析了它们启动流程的异同以及造成这种异同的原因。希望本文对您理解系统的基本启动流程有所帮助&#xff01; 一、Linux系统启动流程 Linux 系统的启动流程可以分为几个主要阶段&#xff0c;从电源开启到用户登录。每个…