题目大意
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.