首页 > 代码库 > 区间最值ST算法

区间最值ST算法

题目描述

给出一大串数字(编号为1到N),给定M个询问,每次询问两个数字A,B,要求A到B这段区间内的最大数。

输入输出格式

输入格式:

 

一个整数N表示数字的个数,接下来一行为N个数。第三行读入一个M,接下来M行,每行都有两个整数A,B。

 

输出格式:

 

输出共M行,每行输出一个数。

 

输入输出样例

输入样例#1:
6
34 1 8 123 3 2
4
1 2
1 5
3 4
2 3
输出样例#1:
34
123
123
8

说明

对于30%的数据,1<=N<=10000,1<=M<=100

对于100%的数据,1<=N<=200000,1<=M<=10000.

 

sparse table

f[i][j]表示从i向前走2^j步之间的最小值

#include<cstdio> 
#include<cmath>
#include<cstring>
#include<algorithm>
int a[400000],f[400000][30];
int n,m;
int max(int a,int b){
    if(a>b) return a;
    return b;
}
void init(){
    for(int i=1;i<=n;++i) f[i][0]=a[i];
    for(int j=1;j<=30;++j)
     for(int i=(1<<j);i<=n;++i)
      f[i][j]=max(f[i][j-1],f[i-(1<<(j-1))][j-1]);//预处理,RMQ
}
int query(int l,int r){
    int x=log(r-l+1)/log(2);
    return max(f[r][x],f[l+(1<<x)-1][x]);//将区间分成两二进制数段
}
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;++i) scanf("%d",&a[i]);
    init();
    scanf("%d",&m);
    for(int i=1;i<=m;++i){
        int l,r;
        scanf("%d %d",&l,&r);
        printf("%d\n",query(l,r));
    }
    return 0;
}

 

区间最值ST算法