PPT1 例1

题意/Description

    桌子上零散地放着若干个盒子,桌子的后方是一堵墙。如右图所示。现在从桌子的前方射来一束平行光, 把盒子的影子投射到了墙上。问影子的总宽度是多少?

读入/Input

不详

20   //桌面总宽度
4    //盒子数量
1 5
3 8
7 10
13 19

输出/Output
    影子的总宽度是多少(15)

题解/solution
    给线段树每个节点增加一个域cover。cover=1表示该结点所对应的区间被完全覆盖,cover=0表示该结点所对应的区间未被完全覆盖。

代码/Code
type
  arr=record
    l,r:longint;
    cover:longint;
  end;
var
  tree:array [0..2001] of arr;
  n,m:longint;
procedure ins(p,a,b:longint);
var
  m:longint;
begin
  with tree[p] do
    begin
      if cover=0 then
        begin
          m:=(l+r) div 2;
          if (l=a) and (r=b) then cover:=1 else
            begin
              if b<=m then ins(p*2,a,b) else
                if a>=m then ins(p*2+1,a,b) else
                  begin
                    ins(p*2,a,m);
                    ins(p*2+1,m,b);
                  end;
            end;
        end;
    end;
end;

function count(p:longint):longint;
begin
  with tree[p] do
    begin
      if cover=1 then count:=r-l else
        if r-l=1 then count:=0 else
          count:=count(p*2)+count(p*2+1);
    end;
end;

procedure cre(p:longint);
var
  m,k:longint;
begin
  k:=p*2;
  with tree[p] do
    begin
      if r-l>1 then
        begin
          m:=(l+r) div 2;
          tree[k].l:=l;
          tree[k].r:=m;
          tree[k+1].l:=m;
          tree[k+1].r:=r;
          cre(p*2);
          cre(p*2+1);
        end;
    end;
end;

procedure main;
var
  i,x,y:longint;
begin
  readln(m);
  tree[1].l:=1; tree[1].r:=m;
  cre(1);
  readln(n);
  for i:=1 to n do
    begin
      readln(x,y);
      ins(1,x,y);
    end;
end;

begin
  main;
  write(count(1));
end.


你可能感兴趣的:(PASCAL,线段树)