RMQ ---- genius of memories

There once was a man named WNB, he has a genius-like memory, his collection of many, many treasures.
After his death, left to posterity a problem (a special test memory ah!), If anyone can easily answer that question, we can inherit his treasures.
Topic is this: to give you a long list of numbers (numbered 11 to NN, size may not necessarily Oh!), After you read it again, it will disappear in front of you, then the question arises, to ask you a MM, Always ask will give you two numbers a, BA, B, ask you to instantly tell the maximum number belong to AA to BB within this interval.
One day, a beautiful sister flew from the sky, see this issue was very interesting (mostly is said that the treasure hidden inside a cosmetic water, drinking can make this beautiful sister more attractive), she would do everything strength in trying to solve this problem.
However, she always ended in failure, because the number of these numbers is too much!
She asked you to help him solve a genius. If you help her solve this problem, but will get a lot of sweetness Oh!
Input format
The first line NN represents an integer number of digits.
Next, the behavior of a number NN, represents a sequence of numbers.
The third line reads a MM, indicates how many times you need to be thankful after reading a few questions.
Next MM lines, each line has two integers A, BA, B.
Output format
output common MM lines, each line of output a number that represents the answer to a question.
Data range
1≤N≤2 × 1051≤N≤2 × 105,

1≤M≤1041≤M≤104
Input Sample:
. 6
34 is 123. 3 2. 8. 1
. 4
. 1 2
. 1. 5
. 3. 4
2. 3

Output Sample:
34 is
123
123
. 8

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cmath>
using namespace std;
const int N = 200010, M = 18;
int n, m;
int w[N];
int f[N][M];
void init(){
 for (int j = 0; j < M; j ++)
   for (int i = 1; i + (1 << j) - 1<= n; i ++)
   if (!j)    f[i][j] = w[i];
   else       f[i][j] = max(f[i][j - 1], f[i + (1 << j - 1)][j - 1]);
}
int query(int l, int r){
 int len = r - l + 1;
 int k = log(len) / log(2);
 return max(f[l][k], f[r - (1 << k) + 1][k]);
}
int main(){
 scanf("%d", &n);
 for (int i = 1; i <= n; i ++)   scanf("%d",&w[i]);
 init();
 scanf("%d", &m);
  while(m --){
  int l, r;
  scanf("%d%d", &l, &r);
  printf("%d\n", query(l, r));
 }
 return 0;
}
Published 106 original articles · won praise 67 · views 5436

Guess you like

Origin blog.csdn.net/qq_45772483/article/details/104787357