您的位置:首页 > 其它

jzoj 1278. 排队 洛谷 P2880 [USACO07JAN]平衡的阵容Balanced Lineup

2017-07-06 20:37 441 查看
Description

  每天,农夫 John 的N(1 <= N <= 50,000)头牛总是按同一序列排队. 有一天, John决定让一些牛们玩一场飞盘比赛. 他准备找一群在对列中为置连续的牛来进行比赛.但是为了避免水平悬殊,牛的身高不应该相差太大.

  John 准备了Q (1 <= Q <= 180,000) 个可能的牛的选择和所有牛的身高 (1 <=身高 <= 1,000,000). 他想知道每一组里面最高和最低的牛的身高差别.

Input

  第一行: N 和 Q.

  第2..N+1行: 第i+1行是第i头牛的身高.

  第N+2..N+Q+1行: 两个整数, A 和 B (1 <= A <= B <= N), 表示从A到B的所有牛.

Output

  第1..Q行: 所有询问的回答 (最高和最低的牛的身高差), 每行一个.

Sample Input

6 3

1

7

3

4

2

5

1 5

4 6

2 2

Sample Output

6

3

0

分析:

这题就是求多次区间最大最小值,rmq模板题。其实线段树也能过。

代码(线段树):

type
node=record
max,min:longint;
end;

var
tree:array [1..100000*2] of node;
h:array [1..100000] of longint;
n,q,i,j,s,t,x,y:longint;

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

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

procedure build(p,l,r:longint);
var mid:longint;
begin
if l=r then
begin
tree[p].max:=h[l];
tree[p].min:=h[l];
exit;
end;
mid:=(l+r) shr 1;
build(p*2,l,mid);
build(p*2+1,mid+1,r);
tree[p].max:=max(tree[p*2].max,tree[p*2+1].max);
tree[p].min:=min(tree[p*2].min,tree[p*2+1].min);
end;

procedure find(p,l,r,x,y:longint; var s,t:longint);
var mid:longint;
ss,tt:longint;
begin
if (l=x) and (r=y) then
begin
s:=tree[p].max; t:=tree[p].min;
exit;
end;
mid:=(l+r) shr 1;
if y<=mid then find(p*2,l,mid,x,y,s,t)
else
begin
if x>mid then find(p*2+1,mid+1,r,x,y,s,t)
else
begin
find(p*2,l,mid,x,mid,s,t);
ss:=s; tt:=t;
find(p*2+1,mid+1,r,mid+1,y,s,t);
if s<ss then s:=ss;
if t>tt then t:=tt;
end;
end;
end;
begin
readln(n,q);
for i:=1 to n do
read(h[i]);
build(1,1,n);
for i:=1 to q do
begin
read(x,y);
find(1,1,n,x,y,s,t);
writeln(s-t);
end;
end.


代码(rmq):

Var n,q,i,j,x,y,k:longint;
fmax,fmin:array[0..100005,0..20] of longint;
a:array[0..100005] of longint;
function max(a,b:longint):longint;
begin
if a>b then max:=a else max:=b;
end;
function min(a,b:longint):longint;
begin
if a>b then min:=b else min:=a;
end;
begin
readln(n,q);
fillchar(fmin,sizeof(fmin),$7f);
for I:=1 to n do
begin
readln(a[i]);
fmin[i,0]:=a[i];
fmax[i,0]:=a[i];
end;
for j:=1 to trunc(ln(n)/ln(2)) do
for i:=1 to n-(1 shl j)+1 do
begin
fmax[i,j]:=max(fmax[i,j-1],fmax[i+1 shl (j-1),j-1]);
fmin[i,j]:=min(fmin[i,j-1],fmin[i+1 shl (j-1),j-1]);
end;
for I:=1 to q do
begin
readln(x,y);
k:=trunc(ln(y-x+1)/ln(2));
writeln(max(fmax[x,k],fmax[y-(1 shl k)+1,k])-min(fmin[x,k],fmin[y-(1 shl k)+1,k]));
end;
end.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: