RMQ问题ST表
稀疏表(Sparse Table表)
解決靜態RMQ,區間最值查詢問題的數據結構,樹狀數組(BIT)解決動態前綴和問題的數據結構;
例:https://www.luogu.org/problemnew/show/P3865
原理:把給定區間分成長度是2的冪次的小區間。先預處理出它們中的最小值是多少,然后用一種類似二分的思想由小區間到大區間比較兩個區間的最小值。
ST算法,設f[i][j]f[i][j]表示從序列的第ii個位置開始ajaj個數的最大值,我們可以得到公式f[i][j]=max(f[i][j?1],f[i+2j?1][j?1])f[i][j]=max(f[i][j?1],f[i+2j?1][j?1]),相當于把一個從ii到2j2j的區間分成了兩個長度為2j?12j?1的區間。當我們查詢最大值的時候,我們可以算出一個kk,就是讓2k<2k<這個區間長度時,kk的最大值,那么我們查詢的區間(l,r)(l,r)的答案就為max(f[l][k],f[r?2k+1][k])max(f[l][k],f[r?2k+1][k]),這兩段剛好覆蓋了這個區間,所以答案是準確的。
?
#include <iostream> #include <cstdio> #include <algorithm> #include <cmath> using namespace std; const int maxn=1e5+10; //區間最值的ST表做法; int n,m,x,y,f[maxn][22]; //一維是端點,二維是長度(二的冪次級別);int main() {scanf("%d%d",&n,&m); //n個元素,m個詢問for(int i=1;i<=n;i++)scanf("%d",&f[i][0]);for(int j=1;j<=20;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]);//每個區間的更新一分為二 }}while(m--){ //ST表的查詢;scanf("%d%d",&x,&y);int k=log2(y-x+1); //區間長度可達的最大的冪次級;printf("%d\n",max(f[x][k],f[y-(1<<k)+1][k]));//從左端點查詢長度為查詢的區間的最大2次冪可達值,在從右端點查詢,這兩個區間一定會有重合,并完全覆蓋查詢區間. }return 0; }?
轉載于:https://www.cnblogs.com/Cloud-king/p/9693102.html
總結
- 上一篇: WPF 将Bitmapsource转
- 下一篇: Jenkins使用