【牛客网】数列区间最大值(树状数组)

题目描述:

输入一串数字,给你M个询问,每次询问就给你两个数字X,Y,要求你说出X到Y这段区间内的最大数。
输入描述:
第一行两个整数N,M表示数字的个数和要询问的次数;
接下来一行为N个数;
接下来M行,每行都有两个整数X,Y。
输出描述:
输出共M行,每行输出一个数。
示例1
输入
10 2
3 2 4 5 6 8 1 2 9 7
1 4
3 8
输出
5
8
备注:
对于全部数据,1≤N≤105,1≤M≤106,1≤X≤Y≤N1 \le N \le10^5,1 \le M \le10^6,1 \le X \le Y \le N1≤N≤105,1≤M≤106,1≤X≤Y≤N。数字不超过C/C++的int范围。

解题思路:

AC代码

#include<iostream>
#include<cstdio>
  using namespace std;
  const int maxn=100010;
  int a[maxn],c[maxn];
  int N,M;
  int lowbit(int x){
    
    return x&(-x);}
  void update(int p,int v){
    
    
  c[p]=v;
  int lx=lowbit(p);
  for(int i=1;i<lx;i<<=1){
    
    
  c[p]=max(c[p],c[p-i]);      
  }
  }
 int getmax(int l, int r){
    
    
 if(l==r) return a[r];
 if(r-lowbit(r)+1==l) return c[r];
 if(r-lowbit(r)+1>l) return max(c[r],getmax(l,r-lowbit(r)));
 else{
    
    
 return max(a[r],getmax(l,r-1));    
 }    
 }
  int main(){
    
    
  scanf("%d%d",&N,&M);
  for(int i=1;i<=N;i++){
    
    
  scanf("%d",&a[i]);
  update(i,a[i]);
  }
  int X,Y;
  for(int i=1;i<=M;i++){
    
    
  scanf("%d%d",&X,&Y);
  printf("%d\n",getmax(X,Y));
  }
  return 0;
  }