问题描述
给定一条长度为m的线段,有n个操作,每个操作有3个数字x,y,z表示把区间[x,y]染成颜色z,询问染完色之后,这条长度为m的线段一共有几种颜色。规定:线段的颜色可以相同。连续的相同颜色被视作一段。问x轴被分成多少段。
样例输入
4 20 //四条,总长度为20
10 19 1
2 9 2
5 13 3
15 17 4
样例输出
7
算法讨论
和前面的线段树练习二差不多,把统计程序改一改就好了,如果两端颜色相同则把段数减一,注意x轴的颜色也算在内。
const
maxn=50000;
var
t:array[1..maxn,1..3] of longint;
i,n,m,x,y,s,lc,rc,c:longint;
function count(p:longint;var lc,rc:longint):longint;
var
tl,tr:longint;
begin
if t[p,3]>=0
then begin
lc:=t[p,3];
rc:=lc;
count:=1
end
else if t[p,2]-t[p,1]>1
then begin
s:=count(p*2,lc,tl)+count(p*2+1,tr,rc);
if (tl=tr) and (tl>0)
then dec(s);
count:=s
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(m,n);
t[1,1]:=1; t[1,2]:=n;
create(1);
for i:=1 to m do
begin
read(x,y,c);
insert(1,x,y,c)
end;
count(1,lc,rc);
write(s)
end.
Pixiv ID:34983272