题面
【题目描述】
农夫 的头牛总是按同一序列排队. 有一天, 决定让一些牛们玩一场飞盘比赛. 他准备找一群在队列中位置连续的牛来进行比赛. 但是为了避免水平悬殊,牛的身高不应该相差太大. 准备了个可能的牛的选择和所有牛的身高 (身高). 他想知道每一组里面最高和最低的牛的身高差别.
【输入】
第行:
第到行:每头牛的身高
第到行:两个整数和,表示从到的所有牛。()
【输出】
输出每行一个数,为最大数与最小数的差
【样例输入】
6 3
1
7
3
4
2
5
1 5
4 6
2 2
【样例输出】
6
3
0
算法分析
ST表模板题目。
a数组表示N头牛的身高。
:表示序列开始,连续个数的最大值。
:表示序列开始,连续个数的最小值。
状态转移方程:
询问区间 ~ 最大、小值?
找到一个,使得
需要满足:
取
区间最大值=
区间最小值=
参考程序
#include<bits/stdc++.h>
#define N 100010
using namespace std;
int f[N][25],s[N][25];
int n,m,x,y;
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%d",&f[i][0]);
s[i][0]=f[i][0]; //初始化
}
for(int j=1;(1<<j)<=n;j++)
for(int i=1;i+(1<<j)-1<=n;i++)
{
f[i][j]=max(f[i][j-1],f[i+(1<<(j-1))][j-1]);
s[i][j]=min(s[i][j-1],s[i+(1<<(j-1))][j-1]);
}
while(m--)
{
scanf("%d%d",&x,&y);
int k=log(y-x+1)/log(2);
printf("%d\n",max(f[x][k],f[y-(1<<k)+1][k])-min(s[x][k],s[y-(1<<k)+1][k]));
}
return 0;
}