Enter a string of numbers and give you MM queries. Each query will give you two numbers X , Y X, Y, asking you to say the maximum number in the interval X X to Y Y.
Input
In the first line, two integers N , M N, M represent the number of digits and the number of inquiries; the
next line is N N numbers; in the
next M M line, each line has two integers X , Y X, Y.
Output
The output is M M lines, and each line outputs a number.
Example
Sample input
10 2
3 2 4 5 6 8 1 2 9 7
1 4
3 8
Sample output
5
8
Hint
For all data, 1 ≤ N ≤ 10 5 , 1 ≤ M ≤ 10 6 , 1 ≤ X ≤ Y ≤ N 1≤N≤105, 1≤M≤106, 1≤X≤Y≤N. The number does not exceed C/C++
the int
range.
The main methods and complexity are as follows:
1. Simple (that is, search), O (n) -O (qn) online.
2.
Line segment tree
, O (n) -O (qlogn) online.
3, ST (in essence,
dynamic programming
), O (nlogn) -O ( q) online.
ST algorithm (Sparse Table), taking the maximum value as an example, let d [i, j] represent the maximum value in the interval [i, i + 2 ^ j-1], then when asked about the interval [a, b] The maximum value of the answer is max (d [a, k], d [b-2 ^ k + 1, k]), where k is the largest one that satisfies 2 ^ k <= b-a + 1 (that is, length) k, that is, k = [ln (b-a + 1) / ln (2)].
The method of seeking d may be
dynamic programming
, d [i, j] = max (d [i, j-1], d [i + 2 ^ (j-1), j-1]).
4. RMQ standard algorithm: first reduce to
LCA
(Lowest Common Ancestor), then reduce to constrained RMQ, O (n) -O (q) online.
First, according to the original
number of columns
, the establishment of
Cartesian tree
, so that the problem
of linear time
statute of the LCA problem. The LCA problem can be reduced to RMQ in linear time, that is, the RMQ problem where the difference between any two adjacent numbers in the sequence is +1 or -1. There are constraints RMQ O (n) -O (1) solution line, so that the whole algorithm
time complexity
is O (n) -O (1) .
#include <bits/stdc++.h> using namespace std; inline int read(){ char ch=getchar();int res=0,f=1; while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9') res=res*10+ch-'0', ch =getchar(); return res*f; } inline void write(int zx){ if(zx<0) zx=-zx,putchar('-'); if(zx<10) putchar(zx+'0'); else{ write(zx/10); putchar(zx%10+'0'); } } int n,m,a[100010],f[100010][20]; void ST(){ 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 RMQ(int l,int r){ int k=0; while((1<<(k+1))<=r-l+1) k++; return max(f[l][k],f[r-(1<<k)+1][k]); } int main(){ n=read();m=read(); for(int i=1;i<=n;i++) a[i]=read(); ST(); for(int i=1;i<=m;i++){ int l=read(),r=read(); write(RMQ(l,r)); putchar('\n'); } return 0; }