ST table
ST table to solve the RMQ (range of most value) issue classical algorithm.
Time complexity \ (O (nlog (n) ) \) pretreatment, \ (O (. 1) \) handles inquiries.
But the ST table can only be used to find static range most value , dynamic range or need to segment tree algorithms.
Fundamental
ST table is based on the multiplication idea, in essence, DP
Consider DP
If \ (f [i] [j ] \) representing the interval \ ([i, j] \ ) of the most value, apparently \ (f [i] [j ] = max / min (f [i] [j -1], a_j) \) , so there is \ (O (n ^ 2) \) complexity, but still not good enough.
So how to optimize it?
ST is the next table, a value of the interval of the most important properties --max operation allows two intervals overlap, i.e., can cover a large interval between two cells of a value introduced most large interval, where necessary using multiplier thought of.
We \ (f [i] [j ] \ :( n * \ log_2 (n)) \) represents from \ (I \) start number, consecutive \ (2 ^ j \) the most value of the number of , i.e., the interval \ ([i, i + 2 ^ j-1] \) most values.
Have:
\(f[i][0]=a_i\)
\(f[i][j]=max/min(f[i][j-1],f[i+2^{j-1}][j-1])\)
So DP transfer equation is how come it?
By definition, \ (F [I] [J] \) represents the \ ([i, i + 2 ^ j-1] \) of most value, \ ([I, I + 2 ^ J-. 1] \ ) will use \ ([i, i + 2 ^ {j-1} -1] \) and \ ([i + 2 ^ { j-1}, i + 2 ^ j-1] \) is covered. Corresponds to \ (F \) on the array, respectively, it is \ (F [I] [J-. 1] \:, \: F [I + J-2 ^ {}. 1] [-J. 1] \) .
Then ask how to deal with:
For inquiries interval \ ([the X-, the y-] \) , we use the \ (f \) array covering it:
From (X \) \ begin fetching right \ (2 ^ {\ lfloor \ log_2 (y-x + 1) \ rfloor} \) number as the left interval from \ (Y \) begins also take \ (^ 2 {\ lfloor \ log_2 (y- x + 1) \ rfloor} \) number as the right section.
Represents a layer section are \ ([x, x + 2 ^ {\ lfloor \ log_2 (y-x + 1) \ rfloor} -1] \) and \ ([y-2 ^ { \ lfloor \ log_2 (y- . 1 + X) \} + rfloor. 1, Y] \) .
Corresponds to \ (F \) array:
设 \(j=\lfloor\log_2(y-x+1)\rfloor\) ,\(Query(x,y)=max/min(f[x][j],f[y-2^j+1][j])\)
附上代码
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
int n,m;
int a[100001];
int f[100001][50];
void init(int n) {
for(int i=1;i<=n;i++) f[i][0]=a[i];
for(int j=1;(1<<j)<=n;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]);
}
int query(int x,int y) {
int j=log(y-x+1)/log(2);
return max(f[x][j],f[y-(1<<j)+1][j]);
}
int main() {
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
init(n);
for(int i=1;i<=m;i++) {
int a,b;
scanf("%d%d",&a,&b);
printf("%d\n",query(a,b));
}
}