PPT1 例4

题意/Description

  x轴上有若干条不同线段,问某个单位区间[x,x+1]上重叠了多少条线段?
 
读入/Input
(不详)
5        //有5条线段
10 19
2 9
5 13
15 17
13 19
15 16    //问的单位区间
 
输出/Output
  问某个单位区间[x,x+1]上重叠了多少条线段
 
题解/solution
  给线段树每个节点增加一个Count域。表示所对应区间上重叠的线段数。
  线段树的构造方法:当某线段能够完整覆盖某个结点所对应的区间时,则不再二分。因此要统计某个单位区间上重叠的线段总数,必须把从叶结点到根结点路径上所有结点的count域累加。所以统计和构造一样要用二分。

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

function count(p:longint):longint;
begin
  ans:=0;
  while p>0 do
    begin
      ans:=ans+tree[p].count;
      p:=p div 2;
    end;
  exit(ans);
end;

procedure find(p,l,r,a,b:longint);
var
  m:longint;
begin
  m:=(l+r) div 2;
  if (l=a) and (r=b) then pt:=p else
    if m>=b then find(p*2,l,m,a,b) else
      if m<=a then find(p*2+1,m,r,a,b) else
        begin
          find(p*2,l,m,a,m);
          find(p*2+1,m,r,m,b);
        end;
end;

procedure main;
var
  i,x,y:longint;
begin
  readln(n);
  m:=100;
  for i:=1 to n do
    begin
      readln(x,y);
      ins(1,1,m,x,y);
    end;
  readln(x,y);
  find(1,1,m,x,y);
end;

begin
  main;
  write(count(pt));
end.
原文地址:https://www.cnblogs.com/zyx-crying/p/9319703.html