區間最值問題-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.pswp.cn/web/41515.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/41515.shtml
英文地址,請注明出處:http://en.pswp.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(…

Kubernets Apiserver IP 段變更后的故障處理

集群Service IP 段變更后&#xff08;從 10.96.0.0/16 變為 10.17.0.0/16&#xff09;&#xff0c;導致 kubernetes.default.svc 的ClusterIP IP &#xff08;10.96.0.1&#xff09;和段范圍不一樣&#xff0c;對于這個情況&#xff0c;需要重建該 svc。 重建方法很簡單&#…

Python28-7.4 獨立成分分析ICA分離混合音頻

獨立成分分析&#xff08;Independent Component Analysis&#xff0c;ICA&#xff09;是一種統計與計算技術&#xff0c;主要用于信號分離&#xff0c;即從多種混合信號中提取出獨立的信號源。ICA在處理盲源分離&#xff08;Blind Source Separation&#xff0c;BSS&#xff0…

運維---關于服務治理Nacos的快問快答

問題&#xff1a;在服務治理中&#xff0c;服務提供者、服務消費者和注冊中心分別承擔著怎樣的角色&#xff1f; 回答&#xff1a; 服務提供者主要負責暴露服務接口&#xff0c;以供其他服務進行調用。 服務消費者的職責是調用其他服務所提供的接口。 注冊中心則承擔著記錄…

【機器學習】(基礎篇一) —— 什么是機器學習

什么是機器學習 本系列博客為你從機器學習的介紹開始&#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

黑馬點評,生成1000個token到redis代碼和1k個token的文件

原來的sql文件里面就可以插入1k個用戶&#xff0c; 這個代碼是從1000個User列表里面生成1k個token到redis里面 ResourceIUserService userService;Resource private StringRedisTemplate stringRedisTemplate;Testpublic void testGetAll() {List<User> users userServ…

activemq推數據給前端的方式

文章目錄 消費者程序接收消息并通過 WebSocket 將消息傳遞給前端 消費者程序接收消息并通過 WebSocket 將消息傳遞給前端 ActiveMQ 是一個開源的消息代理服務&#xff0c;可以用來實現各種消息傳遞模式&#xff0c;包括點對點和發布/訂閱模型。要將數據從 ActiveMQ 推送到前端…

那些年背過的面試題——MySQL篇

本文是技術人面試系列 MySQL 篇&#xff0c;面試中關于 MySQL 都需要了解哪些基礎&#xff1f;一文帶你詳細了解&#xff0c;歡迎收藏&#xff01; WhyMysql&#xff1f; NoSQL 數據庫四大家族 列存儲 Hbase K-V 存儲 Redis 圖像存儲 Neo4j 文檔存儲 MongoDB 云存儲 OSS …

AI大模型的智能心臟:向量數據庫的崛起

在人工智能的飛速發展中,一個關鍵技術正悄然成為AI大模型的智能心臟——向量數據庫。它不僅是數據存儲和管理的革命性工具,更是AI技術突破的核心。隨著AI大模型在各個領域的廣泛應用,向量數據庫的重要性日益凸顯。 01 技術突破:向量數據庫的內在力量 向量數據庫以其快速檢索…

第3章 配置 Vite

1 基本配置 Vite 的配置文件 vite.config.js 是基于 JavaScript 或 TypeScript 的文件&#xff0c;可以使用 ES 模塊語法進行導出。Vite 通過這個配置文件來調整各種構建和開發的選項。 1.1 創建配置文件 在項目根目錄創建 vite.config.js 文件&#xff1a; // vite.config…

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;瀏覽器會阻…

網絡配置文件中type

在網絡配置文件中&#xff0c;type是一個參數&#xff0c;用于指定網絡接口的類型。它指定了網絡接口所使用的協議或技術。 以下是一些常見的type參數值&#xff1a; “ethernet”&#xff1a;表示以太網接口&#xff0c;用于連接以太網設備&#xff0c;如有線網卡。 “wifi”…