题意/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.