ST表———解决静态RMQ问题
应用范围比较窄,只能求解区间最值查询,可以查最大值,也可以查最小值,一般在比赛中会和思维题放在一起考察
还有一种解决静态RMQ问题的是利用线段树
时间复杂度:
线段树:O(nlogn)预处理,单次询问O(logn),空间O(n)
ST表:O(nlogn)预处理,单次询问O(1),空间O(nlogn)
主要掌握好两个函数
第一个是ST表的预处理函数,查最大值和最小值是一样的,在这里我把最大值和最小值都写出来
void ST_init()
{
for(int i=1;i<=n;i++){
fmx[i][0]=a[i];
fmn[i][0]=a[i];
}
int t=log(n)/log(2);
for(int j=1;j<=t;j++){
for(int i=1;i<=n-(1<
}
}
第二个是ST表在某个区间上的查询函数,同样我给出了,最大值和最小值的查询,实际都是一样的操作
int ST_query1(int l,int r)
{
int k=log(r-l+1)/log(2);
return max(fmx[l][k],fmx[r-(1<
int ST_query2(int l,int r)
{
int k=log(r-l+1)/log(2);
return min(fmn[l][k],fmn[r-(1<
题目大意:
找出给定区间的最大值和最小值的差,是道裸题
代码如下:
#include
#include
#include
#include
#include
#include
using namespace std;
const int maxn=5e4+5;
int fmx[maxn][17];
int fmn[maxn][17];
int a[maxn];
int n,q;
void ST_init()
{
for(int i=1;i<=n;i++){
fmx[i][0]=a[i];
fmn[i][0]=a[i];
}
int t=log(n)/log(2);
for(int j=1;j<=t;j++){
for(int i=1;i<=n-(1<
}
}
int ST_query1(int l,int r)
{
int k=log(r-l+1)/log(2);
return max(fmx[l][k],fmx[r-(1<
int ST_query2(int l,int r)
{
int k=log(r-l+1)/log(2);
return min(fmn[l][k],fmn[r-(1<
int main()
{
while(~scanf("%d%d",&n,&q)){
memset(fmx,0,sizeof(fmx));
memset(fmn,0,sizeof(fmn));
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
ST_init();
int l,r;
for(int i=1;i<=q;i++){
scanf("%d%d",&l,&r);
int ans1=ST_query1(l,r);
int ans2=ST_query2(l,r);
///cout<
}
}
return 0;
}