POJ P2777 Count Color

来源:互联网 发布:编程语言的原理 编辑:程序博客网 时间:2024/05/29 18:05

题目大意:
在一个有N个点的线段里,给出多个询问与修改(总共有T个),每次给出一个K。
K=“C”,修改为“X,Y,Z”,即区间[X,Y]染色为Z。
K=“P”,询问为“X,Y”,即求区间[X,Y]的颜色总数。
一开始线段为颜色1,颜色总数不超过M。

1<=N,T<=100000 1<=M<=30

题解:
线段树:
tree[i]>0表示第i个节点所代表的区间的颜色。
tree[i]=-1表示第i个节点所代表的区间为混色区间(区间内有多种颜色)。
1.因为一开始颜色为1,所以一开始建树要经过的节点全部赋值为1。
2.线段树+lazy操作。
3.递归求解。

var      tree:array [0..500001] of longint;      sum:array [0..31] of longint;      i,n,m,t,a,b,c:longint;      k:char;procedure insert(p,l,r,a,b:longint);var      mid:longint;begin      mid:=(l+r) div 2;      if (a=l) and (b=r)         then tree[p]:=c         else begin                  if tree[p]=c then exit;                  if tree[p]<>-1                     then begin                               tree[p * 2]:=tree[p];                               tree[p*2+1]:=tree[p];                               tree[p]:=-1;                          end;                  if b<=mid then insert(p*2,l,mid,a,b)                            else if a>mid then insert(p*2+1,mid+1,r,a,b)                                           else begin                                                     insert(p * 2,l,mid,a,mid);                                                     insert(p*2+1,mid+1,r,mid+1,b);                                                end;              end;end;procedure count(p,l,r,a,b:longint);var      mid:longint;begin      mid:=(l+r) div 2;      if tree[p]<>-1 then         begin              inc(sum[tree[p]]);              exit;         end;       if b<=mid then count(p*2,l,mid,a,b)                 else if a>mid then count(p*2+1,mid+1,r,a,b)                               else begin                                          count(p * 2,l,mid,a,mid);                                          count(p*2+1,mid+1,r,mid+1,b);                                    end;end;procedure print;var     i,ans:longint;begin     ans:=0;     for i:=1 to m do         if sum[i]<>0 then inc(ans);     writeln(ans);end;begin    while not eof do    begin     readln(n,m,t);     fillchar(tree,sizeof(tree),0);     fillchar(sum,sizeof(sum),0);     for i:=1 to 5*n do tree[i]:=1;     for i:=1 to t do           begin                read(k,a,b);                if k='C' then                   begin                         read(c);                         insert(1,1,n,a,b);                   end                   else begin                              fillchar(sum,sizeof(sum),0);                              count(1,1,n,a,b);                              print;                        end;                readln;           end;    end;end.
1 0
原创粉丝点击