现在的位置: 首页 > 综合 > 正文

wikioi3304——by rfy

2018年05月02日 ⁄ 综合 ⁄ 共 2028字 ⁄ 字号 评论关闭

有点区间dp的意思,用线段树记录区间的ans,st搞RMQ

f[x,y]=max{f[x,mid],f[mid+1,y],maxnum(mid+1,y)-minnum(x,mid)} 

我的code:

var
n,i,j,q,x,y:longint;
d,dd:array[1..400000,0..30] of longint;
l,r,v1,v2:array[1..1000000] of longint;

function max(a,b:longint):longint;
begin
if a>b then
  exit(a)
else exit(b);
end;
function min(a,b:longint):longint;
begin
if a<b then
  exit(a)
else exit(b);
end;
function bg(x,y:longint):longint;
var k:longint;
begin
k:=trunc(ln(y-x+1)/ln(2));
exit(max(d[x,k],d[y-1 shl k+1,k]));
end;
function sm(x,y:longint):longint;
var k:longint;
begin
k:=trunc(ln(y-x+1)/ln(2));
exit(min(dd[x,k],dd[y-1 shl k+1,k]));
end;

{function f(x,y:longint):longint;
var ans,mid:longint;
begin
if x=y then
  exit(0);
mid:=(x+y) div 2;
ans:=max(f(x,mid),f(mid+1,y));
ans:=max(ans,bg(mid+1,y)-sm(x,mid));
exit(ans);
end;
function ff(x,y:longint):longint;
var ans,mid:longint;
begin
if x=y then
  exit(0);
mid:=(x+y) div 2;
ans:=max(ff(x,mid),ff(mid+1,y));
ans:=max(ans,bg(x,mid)-sm(mid+1,y));
exit(ans);
end;}

procedure build(p,x,y:longint);
var mid:longint;
begin
l[p]:=x;
r[p]:=y;
if x<>y then
begin
  mid:=(x+y) div 2;
  build(p*2,x,mid);
  build(p*2+1,mid+1,y);
  v1[p]:=max(v1[p*2],v1[p*2+1]);
  v1[p]:=max(v1[p],bg(mid+1,y)-sm(x,mid));
  v2[p]:=max(v2[p*2],v2[p*2+1]);
  v2[p]:=max(v2[p],bg(x,mid)-sm(mid+1,y));
end
else
begin
  v1[p]:=0;
  v2[p]:=0;
end;
end;

function f(p,x,y:longint):longint;
var mid:longint;
begin
if (l[p]=x)and(r[p]=y) then
  exit(v1[p]);
mid:=(l[p]+r[p]) div 2;
if y<=mid then
  exit(f(p*2,x,y));
if x>mid then
  exit(f(p*2+1,x,y));
f:=max(f(p*2,x,mid),f(p*2+1,mid+1,y));
f:=max(f,bg(mid+1,y)-sm(x,mid));
end;

function ff(p,x,y:longint):longint;
var mid:longint;
begin
if (l[p]=x)and(r[p]=y) then
  exit(v2[p]);
mid:=(l[p]+r[p]) div 2;
if y<=mid then
  exit(ff(p*2,x,y));
if x>mid then
  exit(ff(p*2+1,x,y));
ff:=max(ff(p*2,x,mid),ff(p*2+1,mid+1,y));
ff:=max(ff,bg(x,mid)-sm(mid+1,y));
end;

begin
readln(n);
for i:=1 to n do
begin
  read(d[i,0]);
  dd[i,0]:=d[i,0];
end;
for j:=1 to trunc(ln(n)/ln(2)) do
  for i:=1 to n-1 shl j+1 do
  begin
    d[i,j]:=max(d[i,j-1],d[i+1 shl (j-1),j-1]);
    dd[i,j]:=min(dd[i,j-1],dd[i+1 shl (j-1),j-1]);
  end;
build(1,1,n);

readln(q);
for i:=1 to q do
begin
  readln(x,y);
  if x<=y then
    writeln(f(1,x,y))
  else writeln(ff(1,y,x));
end;
end.

抱歉!评论已关闭.