題面
【題目描述】
農夫 的頭牛總是按同一序列排隊. 有一天, 決定讓一些牛們玩一場飛盤比賽. 他準備找一羣在隊列中位置連續的牛來進行比賽. 但是爲了避免水平懸殊,牛的身高不應該相差太大. 準備了個可能的牛的選擇和所有牛的身高 (身高). 他想知道每一組裏面最高和最低的牛的身高差別.
【輸入】
第行:
第到行:每頭牛的身高
第到行:兩個整數和,表示從到的所有牛。()
【輸出】
輸出每行一個數,爲最大數與最小數的差
【樣例輸入】
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;
}