【RMQ&LCA】运动员的身高 解题报告…

【RMQ&LCA】运动员的身高

Time Limit:1000MS  Memory Limit:65536K
Total Submit:12 Accepted:7

Description

运动员的身高(hl.pas/c/cpp)

【问题描述】

  激动人心的2012伦敦奥运会结束了,某国奥运代表团决定要拍一个奥运代表团的合照,为了让每一个人都能出现在第一行的位置,参与合照的运动员都排成一排,照片拍出来后,一个有趣的问题就提出来了,由于运动员之间在拍照的时候并没有按身高进行排列,所以照片中的运动员身高都参差不齐,现在想知道照片中的某两个位置之间所有运动员最高身高的人与最低身高的人身高之差是多少,请你帮忙求出来。

Input

输入第一行是两个数n,m(0< n,m≤10000)表示照片中有n个运动员,第二行有n个数表示照片中从左到右排列的运动员的身高(都是以厘米为单位的整数)。
第3行开始到m+3行,每行两个数ai,bi,表示一个询问,在照片中从左往右第ai个运动员和第bi个运动员之间最高最低身高差是多少。

Output

输出一共m行,每行对应上面的一个询问,两个位置的运动员之间身高最大差是多少。

Sample Input

10 5
1 5 7 3 2 4 5 7 3 1
1 3
4 7
2 9
1 10
5 8

Sample Output

6
3
5
6
5

Source

本站原创

 

用ST算法,来求一个区间[a,b]中的最大值和最小值。

w[i]表示输入的数组

先做预处理,设mi[b,t]表示 b 至 b+2^t-1 中的最值。

 

mi[b,t]:=min(mi[b,t-1],mi[b+2^(t-1),t-1]);

mi[b,0]:=w[b];

 

t可用 trunc(ln(n)/ln(2)) 来算出。

 

 

var
 n,m,i,j,t,l,r:longint;
 w:array[1..10001]of longint;
 mi,ma:array[1..10001,0..15]of longint;
 a:array[0..15]of longint;

function min(x,y:longint):longint;
begin
 if x>y then exit(y)
        else exit(x);
end;

function max(x,y:longint):longint;
begin
 if x<y then exit(y)
        else exit(x);
end;

procedure work;
var
 i,t,len,b:longint;
begin
 len:=trunc(ln(n)/ln(2));
 if a[len+1]<r-l+1 then inc(len);

 

 for i:=1 to n do mi[i,0]:=w[i];
 for t:=1 to len do
  for b:=1 to n-a[t-1]+1 do
   mi[b,t]:=min(mi[b,t-1],mi[b+a[t-1],t-1]);

 

 for i:=1 to n do ma[i,0]:=w[i];
 for t:=1 to len do
  for b:=1 to n-a[t-1]+1 do
   ma[b,t]:=max(ma[b,t-1],ma[b+a[t-1],t-1]);
end;

begin
 read(n,m);
 a[0]:=1;
 for i:=1 to 15 do a[i]:=a[i-1]*2;
 for i:=1 to n do read(w[i]);
 work;
 for i:=1 to m do
  begin
  read(l,r);
  t:=trunc(ln(r-l+1)/ln(2));
  if a[t+1]<r-l+1 then inc(t);
  writeln(max(ma[l,t],ma[r-a[t]+1,t])-min(mi[l,t],mi[r-a[t]+1,t]));
  end;
end.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值