RMQ (Range minimum/maximum Query) The question is: For series A of length n, answer a number of questions RMQ (A,I,J) (i,j<=n), and return to column A and subscript in I, The smallest (large) value in J, that is, the RMQ problem is the problem of finding the maximum interval.
Brief introduction
The main methods and complexity are as follows:
1, simple (that is, search), O (n)-O (qn) online.
2, line tree, O (n)-O (Qlogn) online.
3, ST (essentially dynamic planning), O (Nlogn)-O (1) online.
St Algorithm (Sparse Table), in order to maximize the value for example, set d[i,j] for [i,i+2^j-1] The maximum value in this interval, then asked to the [a, b] interval maximum value when the answer is Max (D[a,k], d[b-2^k+1,k]), where K is satisfied 2 ^k<=b-a+1 (i.e. the length) of the largest k, i.e. K=[ln (b-a+1)/LN (2)].
The method of D can be used in dynamic programming, D[i, J]=max (D[i, j-1],d[i+2^ (j-1), j-1]).
4, RMQ standard algorithm: first statute into LCA (Lowest Common Ancestor), then the Statute into a constraint Rmq,o (n)-O (1) online.
First, the Cartesian tree is established according to the original sequence, thus the problem is regulated as LCA in linear time. The LCA problem can be constrained rmq in linear time, that is, the difference of any two adjacent numbers in the sequence is the RMQ problem of +1 or 1. The constraint rmq has an O (n)-O (1) on-line solution, so the time complexity of the whole algorithm is O (n)-O (1).
St algorithm
Take a look at how the ST algorithm is implemented (in the case of maximum values):
The first is preprocessing, with a DP solution. Set A is the number of intervals requiring the most value, F[i,j] indicates the maximum value from the number of consecutive 2^j from the first. For example, Series 3 2 4 5 6 8 1 2 9 7, f[1,0] represents the 1th number, the maximum length of 2^0=1, is actually 3 this number. F[1,2]=5,f[1,3]=8,f[2,0]=2,f[2,1]=4 ... From here you can see that f[i,0] is actually equal to a. In this way, the DP state, the initial value has already been, the rest is the state transfer equation. We divide F[i,j] (j≥1) evenly into two segments (because J≥1, f[i,j] must be an even number of numbers), from I to i+2^ (j-1)-1 for a paragraph, i+2^ (j-1) to I+2^j-1 for a segment (the length is 2^ (j-1)). Using the example above, when I=1,j=3 is the 3,2,4,5 and 6,8,1,2 the two paragraphs. F is the maximum value in the maximum of these two paragraphs. So we got the equation of motion F[i,j]=max (f[i,j-1],f[i+2^ (j-1), j-1]).
The next is to get the most value, perhaps you can not imagine to calculate the use of F, generally to calculate Max or O (logn), or even O (n). But there is a good way to do it O (1). or separate. As in the above example we require the maximum value of the interval [2,8], it is divided into [2,5] and [5,8] two intervals, because the maximum value of these two intervals we can directly from f[2,2] and f[5,2] get. The extension to the general case is to divide the interval [l,r] into two intervals of length 2^n (guaranteed to have f correspondence). To give an expression directly:
K:=trunc (ln (r-l+1)/LN (2));
Ans:=max (F[l,k],f[r-2^k+1,k]);
This calculates the range from L, length 2^k, and the maximum value of the interval starting from r-2^k+1 length to 2^k (the expression is cumbersome, details such as adding 1 minus 1 need careful consideration), the larger of the two is the maximum value of the entire interval [l,r].
Standard algorithms
Build a flute Karlshu
The Cartesian tree C of the array a[0,n-1] is such a binary tree: When n=0, it is an empty tree, otherwise its root node is a minimum element in a a[i] (and with this smallest element subscript I mark), and the left and right sub-tree is a[0,i-1] and a[i+1,n-1] a cartesian tree. Note that if there are equal elements in a, then A's Cartesian tree is not necessarily unique, but here we limit the minimum element used to be the first in the array, where the Karlshu is unique.
It is easy to see that the minimum value of array A on the closed interval [l,r] is equivalent to the value of the nearest common ancestor (LCA) of the two vertices labeled L and R in the Cartesian tree C. As a result, RMQ problems can be transformed into LCA problems. Here's how to achieve this transformation in O (n) time.
We're going to insert the elements of a into the Cartesian tree C in turn. Each insertion can change the shape of the tree. In order to complete the entire insertion process in O (N) time, consider the right strand of C, that is, the root node, the right son of the root node, the right son of the root node ... Composed of chains. Note that the subscripts and values of these elements are incremented. Subscript Max, the element to be inserted a[i] must be the last element in the right chain of the new tree. In the original right chain, elements larger than a[i] are no longer part of the right chain in the new tree, and the chain of these elements becomes the right strand of the left subtree of A[i], and the other elements in the right chain, plus a[i, make up a new right chain. At first glance, the best way to find the cutoff point is to find the Logn time, but for the whole process, the time complexity of O (NLOGN) is not optimal. The key is that once an element is larger than a[i, it is permanently removed from the right chain. If an element is judged to be greater than a[i in order from back to front, the time complexity of each insertion is O (k+1), and K is the number of right chain elements removed in this insert. Because each element is at most in and out of the right chain, the time complexity of the whole process is O (N).
Using a stack structure to maintain the subscript of the right chain element, the above procedure can be easily implemented. (See Code section below)
Convert to constrained RMQ
In order to transform the LCA problem into a constrained rmq, we note that the LCA of two nodes in any tree is the smallest of the nodes in the depth-first search that starts at the root of the roots, and between U and V (including backtracking). To take advantage of this fact, we create three arrays:
E[1,2*N-1]: A node that arrives at each step in a depth-first search (which happens to be a one-time tour of the tree).
The number of layers in the tree that correspond to nodes in the l[1,2*n-1]:e.
H[1,n]: The subscript of each node in E that appears once (it may be set for the first time).
for any u and V, it is advisable to set H[U]≤H[V] (otherwise switched U and V), as long as the lowest value in L is found in [h[u],h[v]] subscript I, then e[i] is the LCA of U and v. Notice that L satisfies the conditions of the constrained RMQ (the absolute value of the adjacent element difference is 1), which indicates that the original LCA problem has been transformed into a constrained rmq. The conversion process can obviously be done in O (N) time.
The solution of constrained RMQ
Now still using a[0,n-1] to represent the series in question, here are | A[i]-a[i-1]|=1 (i=1,2,..., N-1) was established.
Break A into a block of length l=[(log N)/2]. Set a ' [I] to the minimum value in Block I, B[i] is the position of the minimum value. The length of a ' [I] and b[i] are all n/l, so the space-time complexity of processing a ' array with the ST algorithm is O (N/l*log (n/l)) =o (n/logn* (LOGN-LOGL)) =o (N). After preprocessing, queries for any number of contiguous blocks can be implemented within O (1) time. The rest of the question is how to make an intra-block query.
Note that the only factor that affects the results of queries in blocks within a block is the sequence of "ascending and descending relationships" between each of the two elements in a block. Since there are only two relationships between each of the two elements ("+1", "1"), and the block length is only l=[(log N)/2), there are at most 2^i=o (sqrt N) of the blocks in nature. The space-time complexity of preprocessing the answers for all possible intra-block queries in each block is O (sqrt n*l^2) =o (n) (Here the O (n) indicates no more than linear time). The "type" of all blocks is preprocessed and the time complexity stored with the binary number is O (N).
Thereafter, each query can be divided into two scenarios:
1, block query, the answer has been preprocessed, as long as the array to find it.
2, block between query, can be decomposed into 2 block query, and a ' on the RMQ, the time complexity of the three are O (1).
In conclusion, we give an on-line RMQ algorithm which has a preprocessing time of O (n) and a query time of O (1).
Code
St algorithm, Pascal, program fragment
Read (n, Q);
For I: = 1 to n do
Read (d[i, 0]);
for J: = 1 to Trunc (ln (n)/ln (2)) does
For I: = 1 to n-1 SHL J + 1 Do
D[I,J]: = Max (D[i,j-1], d[i+1 SHL (j-1), j-1]);
For I: = 1 to Q do
Begin
Read (A, b);
K: = Trunc (ln (b-a + 1)/ln (2));
RMQ: = Max (D[a, K], d[b-1 SHL K + 1, K]);
Writeln (RMQ);
End
RMQ (range minimum/maximum Query) The problem is to find the interval most value problem. Of course you can write an O (n) (How to write), but in case you want to ask the most value 1 million times, it is estimated that you are going to hang up. At this point you can safely write a line segment tree (provided that you do not write wrong) O (Logn) complexity should not hang. However, here is the more bull algorithm, is the ST algorithm, it can do O (nlogn) preprocessing, O (1) to answer each query.
St algorithm, Pascal, complete process
var p,n,m,z:longint;
Aa,data:array[0..100001]of Longint;
Procedure Myread;
var i:longint;
Begin
Read (N,M);
For I:=1 to n do read (Aa[i]);
Z:=trunc (sqrt (n));d ata[1]:=maxlongint;p:=1;
For I:=1 to N do
Begin
If AA[I]<DATA[P] then data[p]:=aa[i];
If I mod z=0 then BEGIN Inc (P);d ata[p]:=maxlongint;end;
End
End
Procedure main;
var tt1,tt2,a,b,i,j,t1,t2,min:longint;
Begin
For I:=1 to M do
Begin
Read (A, b);
T1:=a Div z +1;
T2:=b Div z +1;
Tt1:=a MoD z;
Tt2:=b MoD z;
Min:=maxlongint;
If T1=t2 Then
Begin
For J:=a to B do
If MIN>AA[J] then min:=aa[j];
Write (min, ');
Continue
End
For j:= ((t1-1) *z+tt1) to T1*z do
If MIN>AA[J] then min:=aa[j];
For j:= ((t2-1) *z) to ((t2-1) *z+tt2) do
If MIN>AA[J] then min:=aa[j];
For j:=t1+1 to T2-1 do
If MIN>DATA[J] then min:=data[j];
Write (min, ');
End
End
Begin
Myread;main;
End.
St algorithm, C + +
#include <iostream>
#include <cstdio>
#include <cmath>
#define MAX (A, B) (A>B?A:B)
#define MIN (A, b) (A<B?A:B)
#define MN 50005
using namespace Std;
int MI[MN][17],MX[MN][17],W[MN];
int n,q;
void Rmqinit ()
{
int i,j,m;
for (i=1;i<=n;i++) {mi[i][0]=mx[i][0]=w[i];}
M=floor (log (double) n)/log (2.0));
for (i=1;i<=m;i++)
{
for (j=n;j>=1;j--)
{
MX[J][I]=MX[J][I-1];
if (j+ (1<< (i-1)) <=n) Mx[j][i]=max (mx[j][i],mx[j+ (1<< (i-1))][i-1]);
MI[J][I]=MI[J][I-1];
if (j+ (1<< (i-1) <=n)) Mi[j][i]=min (mi[j][i],mi[j+ (1<< (i-1))][i-1]);
}
}
}
int rmqmin (int l,int R)
{
int M=floor (log (double) (r-l+1))/log (2.0));
return min (mi[l][m],mi[r-(1<<m) +1][m]);
}
int Rmqmax (int l,int R)
{
int M=floor (log (double) (r-l+1))/log (2.0));
Return Max (mx[l][m],mx[r-(1<<m) +1][m]);
}
int main ()
{
cin>>n>>q;
for (int i=1;i<=n;i++) scanf ("%d", &w[i]);//cin>>w[i];
Rmqinit ();
int l,r;
for (int i=1;i<=q;i++)
{
scanf ("%d%d", &l,&r);//cin>>l>>r;
printf ("%d%d\n", Rmqmax (L,r), Rmqmin (L,r));
Cout<<rmqmax (l,r) << "" <<rmqmin (l,r) <<endl;
}
while (Cin>>n)
return 0;
}
Build a Cartesian tree, C + +
void Computetree (int a[maxn], int N, int t[maxn])
T[i] Stores the parent node of each node (the left and right subtree is irrelevant)
{
int ST[MAXN], I, k, top =-1;
Start with the empty stack
Step I, we will a[i] into the stack
for (i = 0; i < N; i++)
{
Find the first element less than or equal to A[i]
K = top;
while (k >= 0 && a[st[k]] > A[i])
k--;
Change the structure of the tree as described above
if (k! =-1)
T[i] = st[k];
if (K < top)
T[st[k + 1]] = i;
Insert A[i] into the stack and remove all larger elements
St[++k] = i;
top = k;
}
The first element in the stack is the root, without a parent node
T[st[0]] =-1;
}
Ram Interval Max