算法:线段树
分析:思想跟忠诚2是基本类似的,只需要在原程序中做少量的改动即可,第一次做这道题的时候不知道为什么最后两个点会超时,然后又用堆写,结果只得了一半的分。最后,无奈又回到到了线段树……
program P1607;
const
MaxN=100000;
type
tre=record
lc,rc,l,r,maxdata:longint;
end;
var
m,n,root,tot,x,y,temp:longint;
tree:array [-1..MaxN*4] of tre;
procedure build(var t:longint;l,r:longint);
begin
inc(tot);
t:=tot;
tree[t].l:=l;
tree[t].r:=r;
tree[t].maxdata:=0;
if l=r then exit;
if l<r then
begin
build(tree[t].lc,l,(l+r) div 2);
build(tree[t].rc,(l+r) div 2+1,r);
end;
end;
function max(x,y:longint):longint;
begin
if x>y then exit(x) else exit(y);
end;
function find(t,l,r:longint):longint;
begin
if t=0 then exit;
if (tree[t].l=l) and (tree[t].r=r) then exit(tree[t].maxdata);
if r<=tree[tree[t].lc].r then exit(find(tree[t].lc,l,r))
else if l>=tree[tree[t].rc].l then exit(find(tree[t].rc,l,r))
else exit(max(find(tree[t].lc,l,tree[tree[t].lc].r),find(tree[t].rc,tree[tree[t].rc].l,r)));
end;
procedure change(t,data,l,r:longint);
begin
if t=0 then exit;
if (tree[t].l=x) and (tree[t].r=x) then
begin
tree[t].maxdata:=data;
exit;
end;
if l>=tree[tree[t].rc].l then change(tree[t].rc,data,l,r)
else if r<=tree[tree[t].lc].r then change(tree[t].lc,data,l,r)
else
begin
change(tree[t].lc,data,l,tree[tree[t].lc].r);
change(tree[t].rc,data,tree[tree[t].rc].l,r);
end;
tree[t].maxdata:=max(tree[tree[t].lc].maxdata,tree[tree[t].rc].maxdata);
end;
procedure init;
var
i,j:longint;
ch:char;
begin
root:=0;
tot:=0;
readln(m,n);
build(root,1,m);
for i:=1 to n do
begin
read(ch);
case ch of
'Y':begin
for j:=1 to 4 do read(ch);
readln;
writeln(find(root,1,m));
end;
'L':begin
for j:=1 to 3 do read(ch);
readln(x,y);
change(root,y,x,x);
end;
'U':begin
for j:=1 to 5 do read(ch);
readln(x);
change(root,-10000000,x,x);
end;
end;{case}
end;
end;
begin
assign(input,'P1607.in'); reset(input);
assign(output,'P1607.out'); rewrite(output);
init;
close(input); close(output);
end.
本文通过一个具体的程序实例,详细介绍了线段树算法的应用过程。文章对比了使用堆与线段树的不同效果,并针对线段树的构建、查找及更新等关键操作提供了详细的代码实现。
589

被折叠的 条评论
为什么被折叠?



