线段树练习四

来源:互联网 发布:如何建设网络强国 编辑:程序博客网 时间:2024/05/18 02:33

线段树练习四

Description

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


Sample Input

20 5
10 19
2 9
5 13
15 17
13 19
15 16

Sample Output

3

Hint

 

【数据规模】 
100%满足1≤n≤100000,1≤x≤y≤n


分析:用count[i]记录完全覆盖第i个点的线段的数量,最后询问时累加从子节点到根节点的count。


代码

const
  maxn=1000000;
type
  tnode=record
    a,b:longint;
  end;
var
  tree:array[0..maxn] of tnode;
  cover:array[0..maxn] of longint;
  i,j,n,m,x,y,z,q:longint;


procedure create(p:longint);
var
  m:longint;
begin
  if tree[p].b-tree[p].a>1 then
    begin
      m:=(tree[p].a+tree[p].b) div 2;
      tree[p*2].a:=tree[p].a;
      tree[p*2].b:=m;
      tree[p*2+1].a:=m;
      tree[p*2+1].b:=tree[p].b;
      create(p*2);
      create(p*2+1);
    end;
end;


procedure insert(p,x,y:longint);
var
  m:longint;
begin
  m:=(tree[p].a+tree[p].b) div 2;
  if (tree[p].a=x) and (tree[p].b=y) then inc(cover[p])
    else if y<=m then insert(p*2,x,y)
      else if x>=m then insert(p*2+1,x,y)
        else begin
               insert(p*2,x,m);
               insert(p*2+1,m,y);
             end;
end;


procedure find(p,x,y:longint);
var
  m:longint;
begin
  m:=(tree[p].a+tree[p].b) div 2;
  if (tree[p].a=x) and (tree[p].b=y) then q:=p
    else if y<=m then find(p*2,x,y)
      else if x>=m then find(p*2+1,x,y)
        else begin
               find(p*2,x,m);
               find(p*2+1,m,y);
             end;
end;


function count:longint;
var
  ans:longint;
begin
  ans:=0;
  while q>0 do
    begin
      inc(ans,cover[q]);
      q:=q div 2;
    end;
  exit(ans);
end;


begin
  readln(m,n);
  tree[1].a:=1;
  tree[1].b:=m;
  create(1);
  for i:=1 to n do
    begin
      readln(x,y);
      insert(1,x,y);
    end;
  readln(x,y);
  find(1,x,y);
  writeln(count);
end.


0 0