线段树 例四

来源:互联网 发布:外汇数据接口 编辑:程序博客网 时间:2024/05/17 21:07

题目大意

  x轴上有若干条不同线段,问某个单位区间[x,y]上重叠了多少条线段?

 

分析

  加一个域count,当线段完全覆盖区间[a,b]时,把[a,b]的count域加一。

  思考线段树的构造方法:当某线段能够完整覆盖某个结点所对应的区间时,则不再二分。因此要统计某个单位区间上重叠的线段总数,必须把从叶结点到根结点路径上所有结点的count域累加。

  所以统计算法时,要用和插入算法一样的二分法:使得可以把所有的要加的区间找出来。

 

代码

type  pnode=^tnode;  tnode=record    lc,rc:pnode;    c:longint;end;var  t:pnode;  i,j,k:longint;  x,y:longint;  n,m:longint;  ans:longint;procedure neww(var t:pnode);begin  if t=nil then    begin      new(t);      t^.c:=0;      t^.lc:=nil;      t^.rc:=nil;    end;end;procedure insert(var t:pnode; l,r,x,y:longint);var  i,j,k:longint;  mid:longint;begin  with t^ do    begin      {if c=0 then        begin     }          mid:=(l+r) div 2;          if (l=x) and (r=y)            then              begin                c:=c+1;                exit;              end;          if (l<=x) and (mid>=y)            then              begin                neww(lc);                insert(lc,l,mid,x,y);                exit;              end;          if (mid<=x) and (r>=y)            then              begin                neww(rc);                insert(rc,mid,r,x,y);                exit;              end;          neww(lc);          neww(rc);          insert(lc,l,mid,x,mid);          insert(rc,mid,r,mid,y);      {  end; }    end;end;procedure find(t:pnode;l,r:longint;x,y:longint);var  mid:longint;begin  if t=nil then exit();  {with t^ do    begin      mid:=(l+r) div 2;      if c=1 then exit(r-l);      exit(find(lc,l,mid,x,y)+find(rc,mid,r,x,y));    end; }  with t^ do    begin      {if c=0 then        begin     }          ans:=ans+c;          mid:=(l+r) div 2;          if (l<=x) and (mid>=y)            then              begin                find(lc,l,mid,x,y);                exit;              end;          if (mid<=x) and (r>=y)            then              begin                find(rc,mid,r,x,y);                exit;              end;          find(lc,l,mid,x,mid);          find(rc,mid,r,mid,y);      {  end; }    end;end;begin  readln(m);  readln(n);  fillchar(t,sizeof(t),0);  neww(t);  for i:=1 to n do    begin      readln(x,y);      insert(t,1,m,x,y);    end;  readln(x,y);  find(t,1,m,x,y);  write(ans);end.


1 0
原创粉丝点击