问题描述
桌子上零散地放着若干个不同颜色的盒子,桌子的后方是一堵墙。如右图所示。问从桌子前方可以看到多少个盒子?假设人站得足够远(输入时,由底向上,从左到右)。
样例输入
16 //桌子长度
5 // 盒子数量
4 7
12 14
1 5
6 10
11 16
样例输出
4
算法讨论
构建线段树,我们定义区间标记为-1时表示该区间有多种颜色,标记>=0时表示区间内有单一颜色,统计时如果区间标记>=0,就将该区间的颜色打上标记,最后看有多少个颜色被打上了标记,相加为和。
const
maxn=500000;
var
t:array[1..maxn,1..3] of longint;
f:array[0..maxn] of 0..1;
i,n,m,x,y,s:longint;
function count(p:longint):longint;
begin
if t[p,3]>=0
then f[t[p,3]]:=1
else if t[p,2]-t[p,1]>1
then begin
count(p*2);
count(p*2+1)
end;
end;
procedure insert(p,a,b,c:longint);
var
m:longint;
begin
if t[p,3]<>c
then begin
m:=(t[p,1]+t[p,2]) div 2;
if (t[p,1]=a) and (t[p,2]=b)
then t[p,3]:=c
else begin
if t[p,3]>=0
then begin
t[p*2,3]:=t[p,3];
t[p*2+1,3]:=t[p,3];
t[p,3]:=-1
end;
if b<=m
then insert(p*2,a,b,c)
else if a>=m
then insert(p*2+1,a,b,c)
else begin
insert(p*2,a,m,c);
insert(p*2+1,m,b,c)
end;
end;
end;
end;
procedure create(p:longint);
var
m:longint;
begin
if t[p,2]-t[p,1]>1
then begin
m:=(t[p,1]+t[p,2]) div 2;
t[p*2,1]:=t[p,1]; t[p*2,2]:=m;
t[p*2+1,1]:=m; t[p*2+1,2]:=t[p,2];
create(p*2);
create(p*2+1)
end;
end;
begin
read(n,m);
for i:=1 to maxn do
t[i,3]:=-1;
t[1,1]:=1; t[1,2]:=n;
create(1);
for i:=1 to m do
begin
read(x,y);
insert(1,x,y,i)
end;
count(1);
for i:=0 to maxn do
if f[i]=1
then inc(s);
write(s)
end.
Pixiv ID:60328522