线段树练习题三

线段树练习题三

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.


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值