Sparse Table [RMQ]
预处理时间复杂度 O(NlogN) O ( N l o g N ) ,查询时间复杂度 O(1) O ( 1 ) 。很优秀。
f[i][j]
f
[
i
]
[
j
]
表示[i,i+2^(j-1)]
区间中的最大/最小值。
方程:f[i][j]=min(f[i][j-1],f[i+2^(j-1)][j-1])
代码
#include<iostream>
#include<cstdio>
#include<cmath>
#define N 50050
using namespace std;
int h[N],Fmin[N][20],Fmax[N][20];
void Get(int n){
int k=floor(log2(n));
for(int j=1;j<=k;j++)
for(int i=1;i<=(n-(1<<j)+1);i++){
Fmin[i][j]=min(Fmin[i][j-1],Fmin[i+(1<<(j-1))][j-1]);
Fmax[i][j]=max(Fmax[i][j-1],Fmax[i+(1<<(j-1))][j-1]);
}
}
int Findmax(int x,int y){
int k=floor(log2(y-x+1));
return max(Fmax[x][k],Fmax[y-(1<<k)+1][k]);
}
int Findmin(int x,int y){
int k=floor(log2(y-x+1));
return min(Fmin[x][k],Fmin[y-(1<<k)+1][k]);
}
int main(){
int n,q;scanf("%d%d",&n,&q);
for(int i=1,t;i<=n;i++)
scanf("%d",&t),Fmin[i][0]=t,Fmax[i][0]=t;
Get(n);//预处理
for(int i=1;i<=q;i++){
int a,b;scanf("%d%d",&a,&b);
printf("%d\n",Findmax(a,b)-Findmin(a,b));
}
return 0;
}