线段树练习题二
Description
桌子上零散地放着若干个不同颜色的盒子,桌子的后方是一堵墙。如右图所示。问从桌子前方可以看到多少个盒子?假设人站得足够远(输入时,由底向上,从左到右)。
分析:cover=0表示该区间由多种颜色组成。cover>0表示该区间只有一种单一的颜色cover,最后用个桶统计一下。注意:覆盖时不能完全覆盖的话要把该区间的cover变为0。
代码
const
maxn=100000;
type
tnode=record
a,b:longint;
end;
var
tree:array[0..maxn] of tnode;
cover:array[0..maxn] of longint;
f:array[0..maxn] of boolean;
i,j,n,m,ans,x,y: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,c:longint);
var
m:longint;
begin
if cover[p]<>c then
begin
m:=(tree[p].a+tree[p].b) div 2;
if (x=tree[p].a) and (y=tree[p].b)
then cover[p]:=c
else begin
if cover[p]>0 then
begin
cover[p*2]:=cover[p];
cover[p*2+1]:=cover[p];
cover[p]:=0;
end;
if y<=m
then insert(p*2,x,y,c)
else if x>=m
then insert(p*2+1,x,y,c)
else begin
insert(p*2,x,m,c);
insert(p*2+1,m,y,c);
end;
end;
end;
end;
procedure count(p:longint);
var
m:longint;
begin
if cover[p]>0
then f[cover[p]]:=true
else if tree[p].b-tree[p].a>1
then begin
count(p*2);
count(p*2+1);
end;
end;
begin
readln(m);
tree[1].a:=1;
tree[1].b:=m;
create(1);
readln(n);
for i:=1 to n do
begin
readln(x,y);
insert(1,x,y,i);
end;
count(1);
for i:=1 to n do
if f[i] then inc(ans);
writeln(ans);
end.