您的位置:首页 > 其它

HDU 1823 pascal

2013-06-25 23:05 260 查看
这题是二维线段树的简单题目

简单来说就是单点修改

查询一个区域内的最大值

二维线段树很简单,空间是一维的平方

修改一次的代价是一维的平方

询问也是一维的平方

外围的大线段数不用更新

需要更新的是每个节点里的小线段数

修改一个节点的线段数的代价是Log

共有log个节点。

这题目的询问操作会有l>r的情况 要注意

附上code:

var
c:char;
t1,t2:double;
n,i,x,x1,x2,y,y1,y2,z,ans,tmp:longint;
lx,ly,rx,ry:array[0..5005] of longint;
f:array[0..500,0..5000] of longint;
procedure make(h,k,y1,y2:longint);
var
mid:longint;
begin
ly[k]:=y1;ry[k]:=y2;
f[h,k]:=-1;
if y1=y2 then exit;
mid:=(y1+y2) div 2;
make(h,k*2,y1,mid);
make(h,k*2+1,mid+1,y2);
end;
procedure build(k,x1,x2,y1,y2:longint);
var
mid:longint;
begin
lx[k]:=x1;rx[k]:=x2;
make(k,1,y1,y2);
if x1=x2 then exit;
mid:=(x1+x2) div 2;
build(k*2,x1,mid,y1,y2);
build(k*2+1,mid+1,x2,y1,y2);
end;
function max(a,b:longint):longint;
begin
if a<b then max:=b else max:=a;
end;
procedure update(h,k,y:longint);
var
mid:longint;
begin
f[h,k]:=max(f[h*2,k],f[h*2+1,k]);
if ly[k]=ry[k] then exit;
mid:=(ly[k]+ry[k]) div 2;
if y<=mid then update(h,k*2,y) else update(h,k*2+1,y);
end;
procedure insert(h,k,y,z:longint);
var
l,r,mid:longint;
begin
l:=ly[k];r:=ry[k];
if z>f[h,k] then begin f[h,k]:=z;;end;
if (l=r) then exit;
mid:=(l+r) div 2;
if y<=mid then insert(h,k*2,y,z) else insert(h,k*2+1,y,z);
end;
procedure insertx(k,x,y,z:longint);
var
l,r,mid:longint;
begin
l:=lx[k];r:=rx[k];
if (l=r) then begin  insert(k,1,y,z);exit;end;
mid:=(l+r) div 2;
if x<=mid then insertx(k*2,x,y,z) else insertx(k*2+1,x,y,z);
update(k,1,y);
end;
function find(h,k,y1,y2:longint):longint;
var
l,r,mid,t1,t2:longint;
begin
l:=ly[k];r:=ry[k];
if (y1<=l) and (y2>=r) then begin find:=f[h,k];exit;end;
mid:=(l+r) div 2;
if y1<=mid then t1:=find(h,k*2,y1,y2) else t1:=-1;
if y2> mid then t2:=find(h,k*2+1,y1,y2) else t2:=-1;
if t2>t1 then t1:=t2;
find:=t1;
end;
function findx(k,x1,x2,y1,y2:longint):longint;
var
l,r,mid,t1,t2:longint;
begin
l:=lx[k];r:=rx[k];
if (x1<=l) and (x2>=r) then begin findx:=find(k,1,y1,y2);exit;end;
mid:=(l+r) div 2;
if x1<=mid then t1:=findx(k*2,x1,x2,y1,y2) else t1:=-1;
if x2> mid then t2:=findx(k*2+1,x1,x2,y1,y2) else t2:=-1;
if t2>t1 then t1:=t2;
findx:=t1;
end;
begin
readln(n);
while n<>0 do begin
fillchar(lx,sizeof(lx),0);
fillchar(rx,sizeof(rx),0);
fillchar(ly,sizeof(ly),0);
fillchar(ry,sizeof(ry),0);
fillchar(f,sizeof(f),0);
build(1,100,200,0,1000);
for i:= 1 to n do
begin
read(c);
if c='I' then
begin
read(x);readln(t1,t2);
t1:=t1+0.00001;t2:=t2+0.00001;
y:=trunc(t1*10);z:=trunc(t2*10);
insertx(1,x,y,z);
end
else
begin
read(x1,x2);readln(t1,t2);
t1:=t1+0.00001;t2:=t2+0.00001;
y1:=trunc(t1*10);y2:=trunc(t2*10);
if x1>x2 then begin tmp:=x1;x1:=x2;x2:=tmp;end;
if y1>y2 then begin tmp:=y1;y1:=y2;y2:=tmp;end;
ans:=findx(1,x1,x2,y1,y2);
if ans=-1 then writeln(ans) else
begin
write(ans div 10,'.');
writeln(ans mod 10);
end;
end;
end;readln(n);end;
end.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: