Balanced Lineup
题目地址:添加链接描述
题目大意:求数组内任意两数之间的(最大值-最小值)
解题思路:倍增、ST表,具体见代码:
#include <iostream>
#include<math.h>
#include<stdio.h>
using namespace std;
const int maxn=5e4+7;
const int maxnum=21;
int mmax[maxn][22],mmin[maxn][22],a;//储存最大、最小值的数组
int ST(int l,int r){//ST表读取
int s=log2(r-l+1);
int x=max(mmax[l][s],mmax[r-(1<<s)+1][s]);//从左往右、从右到左求出部分最大值后合并。
int y=min(mmin[l][s],mmin[r-(1<<s)+1][s]);//同上
return x-y;//返回差值
}
int main() {
int n,q;
cin>>n>>q;
//数据较多,下面的输入用cin会TLE
for(int i=1;i<=n;i++){
scanf("%d",&a);
mmax[i][0]=a;
mmin[i][0]=a;
}
//ST表:
for(int i=1;i<=maxnum;i++)//根据数据的取值大小决定
for(int k=1;k+(1<<(i-1))<=n;k++){//注意这里k的范围表示
//调出k到k+2^(i-1),2^(i-1)到k+2^i两个区间最大值,然后合并
mmax[k][i]=max(mmax[k][i-1],mmax[k+(1<<(i-1))][i-1]);
//同理
mmin[k][i]=min(mmin[k][i-1],mmin[k+(1<<(i-1))][i-1]);
}
for(int i=0;i<q;i++){
int l,r;
scanf("%d%d",&l,&r);
printf("%d\n",ST(l,r));//调用即可
}
return 0;
}