Talking about the ST table and talking about the st table
I found that all I learned was false ST table QWQ.
ST table
The functions of the ST table are simple.
It is a powerful tool to solve the RMQ problem (the highest value in the range ).
It can perform $ O (nlogn) $ preprocessing and $ O (1) $ query the maximum value.
Algorithm
The ST table usesMultiplyIdea
Take the maximum value as an example.
We use $ Max [I] [j] $ to represent$2 ^ j $ countFor example, $ Max [I] [1] $ indicates the maximum values of the two numbers in the $ I $ position and $ I + 1 $ position.
In this case, we can split the current interval into two intervals and take the maximum values respectively (Note that the number here starts from $1 $)
Query is also relatively simple
We calculated $ log_2 {(Interval Length)} $
Then, the left and right endpoints are queried separately. This ensures that the query interval can be overwritten.
At the beginning, I didn't quite understand why the left endpoint was $ R-2 ^ k + 1 $ when I started querying from the right endpoint.
Actually quite simple, as we need to find a point $ x $, making $ x + 2 ^ k-1 = r$
In this way, you can get $ x = R-2 ^ k + 1 $
The above may be abstract. We suggest you draw a picture to understand it.
Code
With the above knowledge, the code is better understood.
# Include <cstdio> # include <cmath> # include <algorithm> using namespace std; const int MAXN = 1e6 + 10; inline int read () {char c = getchar (); int x = 0, f = 1; while (c <'0' | c> '9') {if (c = '-') f =-1; c = getchar () ;}while (c >='0' & c <= '9') {x = x * 10 + c-'0 '; c = getchar ();} return x * f;} int Max [MAXN] [21]; int Query (int l, int r) {int k = log2 (r-l + 1); return max (Max [l] [k], Max [r-(1 <k) + 1] [k]); // obtain the greatest value of the split interval} int main () {# ifdef WIN32 freopen (". in "," r ", stdin); # endif int N = read (), M = read (); for (int I = 1; I <= N; I ++) Max [I] [0] = read (); for (int j = 1; j <= 21; j ++) for (int I = 1; I + (1 <j)-1 <= N; I ++) // note that the boundary Max [I] [j] = max (Max [I] [J-1], Max [I + (1 <(J-1)] [J-1]); // if you do not understand the boundary, it is recommended to take a good look at the figure for (int I = 1; I <= M; I ++) {int l = read (), r = read (); printf ("% d \ n", Query (l, r);} return 0 ;}