小熊的早餐(TYVJ1607)

本文通过一个具体的程序实例,详细介绍了线段树算法的应用过程。文章对比了使用堆与线段树的不同效果,并针对线段树的构建、查找及更新等关键操作提供了详细的代码实现。
算法:线段树

分析:思想跟忠诚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.


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值