ST 表算法用于查询区间最值,为静态算法,查询区间最值时不能更新信息,预处理复杂度为 O(nlongn),查询为 O(1)。适用于不更新信息且查询很多的问题。
题意:求解范围内最高的奶牛和最短的奶牛之间的高度差异。
RMQ
#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
const int maxx=5e4+10;;
const int inf=0x3f3f3f3f;
int a[maxx];
int n,q;
int m;
int maxsum[maxx][50],minsum[maxx][50];
void RMQ(){
for(int i=1;i<=n;i++){
maxsum[i][0]=minsum[i][0]=a[i];
}
for(int j=1;(1<<j)<=n;j++){
for(int i=1;i+(1<<j)-1<=n;i++){
minsum[i][j]=min(minsum[i][j-1],minsum[i+(1<<(j-1))][j-1]);
maxsum[i][j]=max(maxsum[i][j-1],maxsum[i+(1<<(j-1))][j-1]);
}
}
}
int maxl,minl;
void Query(int l,int r){
int k=(int)((log(r-l+1))/log(2.0));
maxl=max(maxsum[l][k],maxsum[r-(1<<k)+1][k]);
minl=min(minsum[l][k],minsum[r-(1<<k)+1][k]);
cout<<maxl-minl<<endl;
}
int main(){
int t;
while(scanf("%d %d",&n,&m)!=EOF){
memset(a,0,sizeof(a));
memset(maxsum,0,sizeof(maxsum));
memset(minsum,0,sizeof(minsum));
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
}
RMQ();
for(int i=1;i<=m;i++){
int left,right;
scanf("%d %d",&left,&right);
if(left>right)swap(left,right);
Query(left,right);
}
}
return 0;
}