RMQ區間最值查詢SparseTable演算法
//一維區間最值查詢模板稀疏表sparse table演算法
//區間最值查詢--線段樹--RMQ
//區間連續和--線段樹
//區間第k大--快排--劃分樹(線段樹?) --主席樹
//二維區間最值查詢根據一維區間最值查詢的思想寫程式碼
/*
區間最值查詢RMP ST 演算法
原理: O(nlogn)預處理,O(1) 查詢
預處理--使用動態規劃,令F(i,j)表示以i起始的2^j長的子序列
F[i,0]即為原序列的每一個數,
有狀態轉移方程F(i, j ) = max(F(i,j-1), F(i+ (1<<(j-1)) , j-1 )
查詢----對於i,j區間最值RMP(A,i,j)
他的長度為 j-i+1
令k = log2( j - i + 1)
有i~j區間的最值max(F(i,k) , F[j- (1<<k) + 1 , k ) )
複雜度 預處理 O(nlogn)
查詢 O(1)
應用 線上查詢區間最值
*/
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std ;
const int maxn = 1e5 + 10 ;
//F[i][j] 表示[i , i + ( 1<< j )- 1] 區間的最值
int F[maxn][20 + 1] ;
void RMQ(int n ){
//j必須在外迴圈, 因為狀態轉移方程是從j-1 到j , 也就是說要計算j,即必須計算完j-1的所有數
//j代表區間長度1<<j,他指的是[i, i + ( 1<< j ) -1 ] 的區間的區間長度是 1<< j
for ( int j = 1 ; j<= 20 ;j ++)
//i代表區間起點i
//區間[ i , i+ (1<<j) -1 ] 的最值為兩部分割槽間[i , i + (1<<(j-1)) -1 ] 和[ i + (1<<(j-1)) , i + ( 1<<j) -1] 的最值
// F[i,j] = max( F[i , j-1] , F[i + (1<<(j-1)) +1 , j-1])
for(int i = 1 ; i <= n ;i ++)
//保證第二個子區間下標在區間範圍內
if( i + ( 1<<(j-1)) <= n )
F[i ] [j]= max( F[i][j-1] , F[i + (1<<(j-1))] [ j -1] ) ;
}
int query(int i , int j ){
//劃分區間長度讓結果為兩部分子區間的比較值
//取子區間為前1<<k個數和後1<<k個數
int k = log10( j - i + 1.0) / log10 (2.0) ;
return max( F[i][ k ] , F[j - ( 1<<k ) + 1] [ k]) ;
}
int main(){
//n代表序列長度,m代表詢問個數
int n , m ;
cin>>n>>m ;
for(int i = 1 ;i <= n ; i ++){
cin>>F[i][0] ;
}
RMP( n ) ;
while(m--){
int i , j ;
cin>>i >> j ;
int ans = query( i , j) ;
cout<<ans<<endl;
}
return 0 ;
}
相關推薦
RMQ區間最值查詢SparseTable演算法
//一維區間最值查詢模板稀疏表sparse table演算法 //區間最值查詢--線段樹--RMQ //區間連續和--線段樹 //區間第k大--快排--劃分樹(線段樹?) --主席樹 //二維區間最值
RMQ 區間最值查詢演算法
RMQ(Range Minimum/Maximum Query),對於長度為n的數列A,回答若干詢問RMQ(A,i,j)(i,j<=n),返回數列A中下標在i,j裡的最小(大)值。 主要方法: 樸素(即搜尋),複雜度為O(n)線段樹能在對數時間內在陣列區間上進行
nyoj 119士兵殺敵(三)(線段樹區間最值查詢,RMQ算法)
信息 include out online log 每次 left 一行 [0 題目119 題目信息 執行結果 本題排行 討論區 士兵殺敵(三) 時間限制:2000 ms | 內存限制:65535 KB 難度:5
區間最值查詢(RMQ)
ST演算法 預處理第i位起連續2^k個數的最大值,快速查詢。 說明:定義陣列dp[i][j]表示 從第i位起連續2^j個數 的最大值。 (區間內有2^j個數) 例子: 2 5 9 6 3 1
ST表-求RMQ(區間最值)問題。
Code: #include<bits/stdc++.h> using namespace std; const int MAX = 2000; int n, m, x, y; int a[MAX + 5], lg[MAX + 5], maxn[MAX + 5][MAX + 5];
hdu 1754 I Hate It(線段樹 單點替換區間 最值查詢)
Problem Description 很多學校流行一種比較的習慣。老師們很喜歡詢問,從某某到某某當中,分數最高的是多少。 這讓很多學生很反感。 不管你喜不喜歡,現在需要你做的是,就是按照老師的要求,寫一個程式,模擬老師的詢問。當然,老師有時候需要更新某位同學的成績。
rmq區間最值
const int maxn=1000; const int maxb=10;//maxb=log2(maxn) int n; int a[maxn+5]; int d[maxn+5][maxb+5]
(一)線段樹入門--區間最值查詢
這是一篇入門文章,不過需要你知道啥是二叉樹,並且知道遞迴,本文會持續更新,時間看作者心情。 線段樹 描述 分類:二叉樹搜尋樹 節點結構: struct node { int l,r;//範圍【l,r】 }tr[100];
RMQ區間最值 倍增求法
void init_rmq(int n) { for(int i=1;i<=n;i++) f[i][0]=a[i]; for(int j=1;j<=20;j++)
RMQ(區間最值問題)
ont 技術分享 要求 span max image range style 問題 問題: RMQ (Range Minimum/Maximum Query)問題是指:對於長度為n的數列A,回答若幹詢問RMQ(A,i,j)(i,j<=n),返回數列A中下標在i,
快速查詢區間最值——RMQ演算法(ST實現)
概述 RMQ(Range Minimum/Maximum Query),即區間最值查詢,是指這樣一個問題:對於長度為n的數列A,回答若干詢問RMQ(A,i,j)(i,j<=n),返回數列A中下標在i,j之間的最小/大值。這兩個問題是在實際應用中經常遇到
快速查詢區間最值——RMQ演算法(線段樹實現程式碼)
要求找出區間內的最大最小值的差。 #include<stdio.h> #include<string.h> #include<math.h> #define lso
hdu1754-I Hate It 線段樹RMQ演算法求區間最值問題
I Hate It Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total
RMQ(快速查詢區間最值)
#include <stdio.h> #include <stdlib.h> #include <iostream> #include <string.h&g
RMQ區間最大值與最小值查詢
pan arp max class spa div light min csharp RMQ復雜度:建表$O\left ( nlgn \right ) $,查詢$O\left ( 1 \right )$ ll F_Min[maxn][20],F_Max[max
【線段樹查詢區間最值】poj 3264 Balanced Lineup
truct pri scan aps pre sca print logs oid 1 #include<cstdio> 2 #include<algorithm> 3 using namespace std; 4 5 const i
RMQ 區間最大值最小值 最頻繁次數
2.0 spa log mes num cst color 順序 max 區間的最大值和最小值 #include <cstdio> #include <cstring> #include <cmath> #include <ios
筆記:RMQ(區間最值)之ST算法
運算 不變 想要 parse 計算機語言 c++ 是我 動態規劃 容易 RMQ(區間最值)之ST算法 RMQ即Range Minimum/Maximun Query 中文意思:查詢一個區間的最小值/最大值 比如有這樣一個數組:A{3 2 4 5 6 8 1 2 9 7},
BZOJ1513:樹套樹之線段樹套線段樹實現二維區間修改和最值查詢
name names algo getch oid min 投影 協調 pan 我們經常提及的二維線段樹有兩種寫法,一種是四分樹,一種是樹套樹,寫成四分樹的都是神仙。 樹套樹寫法還是比較好理解的,不過要是讓自己硬套的話可能很不容易套出來的 這裏的二維線段樹,外層線段樹是對方
RMQ算法區間最值
nbsp 覆蓋 main 明顯 else while int 最大值 turn 問題類型:是多次詢問一個大區間裏子區間的最值問題 dp + 位運算的思想處理 rmax[i][j]表示從i開始到i + 2^j - 1的區間裏的最大值dp[i][j] ==== (i,i + 2