线段树练习题三
Description
给定一条长度为m的线段,有n个操作,每个操作有3个数字x,y,z表示把区间[x,y]染成颜色z,询问染完色之后,这条长度为m的线段一共有几种颜色。规定:线段的颜色可以相同。连续的相同颜色被视作一段。问x轴被分成多少段。
分析:与练习二差不多,统计的时候如果当前左子树的最右颜色与右子树的最左颜色相同,ans-1。
代码
const
maxn=100000;
type
tnode=record
a,b:longint;
end;
var
tree:array[0..maxn] of tnode;
cover:array[0..maxn] of longint;
i,j,n,m,c,x,y,ans,lc,rc: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]:=-1;
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;
function count(p:longint;var lc,rc:longint):longint;
var
m,tl,tr:longint;
begin
if cover[p]>=0
then begin
lc:=cover[p];
rc:=lc;
count:=1;
end
else if tree[p].b-tree[p].a>1
then begin
ans:=count(p*2,lc,tl)+count(p*2+1,tr,rc);
if (tl=tr) and (tl>0) then dec(ans);
count:=ans;
end;
end;
begin
readln(n,m);
tree[1].a:=1;
tree[1].b:=m;
create(1);
for i:=1 to n do
begin
readln(x,y,c);
insert(1,x,y,c);
end;
writeln(count(1,lc,rc));
end.