poj2777 Count Color 2011-12-20

Count Color

Time Limit: 1000MSMemory Limit: 65536K

Total Submissions: 23937Accepted: 7078

Description

 

Chosen Problem Solving and Program design as an optional course, you are required to solve all kinds of problems. Here, we get a new problem. 

 

There is a very long board with length L centimeter, L is a positive integer, so we can evenly divide the board into L segments, and they are labeled by 1, 2, ... L from left to right, each is 1 centimeter long. Now we have to color the board - one segment with only one color. We can do following two operations on the board: 

 

1. "C A B C" Color the board from segment A to segment B with color C. 

2. "P A B" Output the number of different colors painted between segment A and segment B (including). 

 

In our daily life, we have very few words to describe a color (red, green, blue, yellow…), so you may assume that the total number of different colors T is very small. To make it simple, we express the names of colors as color 1, color 2, ... color T. At the beginning, the board was painted in color 1. Now the rest of problem is left to your. 

Input

 

First line of input contains L (1 <= L <= 100000), T (1 <= T <= 30) and O (1 <= O <= 100000). Here O denotes the number of operations. Following O lines, each contains "C A B C" or "P A B" (here A, B, C are integers, and A may be larger than B) as an operation defined previously.

Output

 

Ouput results of the output operation in order, each line contains a number.

Sample Input

 

2 2 4

C 1 1 2

P 1 2

C 2 2 2

P 1 2

Sample Output

 

2

1

Source

 

POJ Monthly--2006.03.26,dodo

 

______________________________________________________

 

题目大意:给一个初始为颜色1的板染色,询问一个区间有多少种颜色。

———————————————————————————

颜色最多只有30种,所以需要用一个30位的二进制数表示每段的状态,用线段树修改和查询,基础的线段树水题。= =

 

______________________________________________________

 

  1 Program Stone;
  2 
  3 var n,o,m,lc,rc,x,ans:longint;
  4 
  5     a:array[1..1 shl 18]of longint;
  6 
  7     b:array[1..1 shl 18]of boolean;
  8 
  9  
 10 
 11  procedure update(head,tail,num:longint);    //修改
 12 
 13  var i,j,k:longint;
 14 
 15   begin
 16 
 17    if (head>=lc)and(tail<=rc) then          //如果目前访问的区间被所需修改的区间包括,则整个区间标为x色。x为当前要涂成的颜色
 18 
 19      begin
 20 
 21       a[num]:=1 shl (x-1);
 22 
 23       b[num]:=true;                        //b表示该区间是否都为同一种颜色。
 24 
 25       exit;                                //因为整个区间修改,所以可以直接返回。
 26 
 27      end;
 28 
 29    if b[num] then begin                       
 30 
 31                    a[num*2]:=a[num];a[num*2+1]:=a[num];       //将该区间的状态传递给左右孩子区间。
 32 
 33                    b[num*2]:=true;b[num*2+1]:=true;
 34 
 35                    b[num]:=false;                             //并修改标记。
 36 
 37                   end;
 38 
 39    k:=(head+tail)div 2;
 40 
 41    if k>=rc then update(head,k,num*2) else                  
 42 
 43    if lc>k  then update(k+1,tail,num*2+1) else
 44 
 45     begin
 46 
 47       update(head,k,num*2);
 48 
 49       update(k+1,tail,num*2+1); 
 50 
 51     end;                                                    //分别访问孩子区间。
 52 
 53    a[num]:=a[num*2]or a[num*2+1];                           //使用or计算当前区间的颜色数。
 54 
 55   end;
 56 
 57  
 58 
 59  procedure query(head,tail,num:longint);        //询问
 60 
 61  var i,j,k:longint;
 62 
 63   begin
 64 
 65    if (head>=lc)and(tail<=rc) then
 66 
 67      begin
 68 
 69       ans:=ans or a[num];                      //计算答案
 70 
 71       exit;
 72 
 73      end;
 74 
 75    if b[num] then begin
 76 
 77                    a[num*2]:=a[num];a[num*2+1]:=a[num];
 78 
 79                    b[num*2]:=true;b[num*2+1]:=true;
 80 
 81                    b[num]:=false;
 82 
 83                   end;
 84 
 85    k:=(head+tail)div 2;
 86 
 87    if k>=rc then query(head,k,num*2) else
 88 
 89    if lc>k  then query(k+1,tail,num*2+1) else
 90 
 91     begin
 92 
 93       query(head,k,num*2);
 94 
 95       query(k+1,tail,num*2+1);
 96 
 97     end;
 98 
 99   end;
100 
101  
102 
103  procedure init;
104 
105  var i,j,k:longint;
106 
107      c,sp:char;
108 
109   begin
110 
111    fillchar(b,sizeof(b),false);
112 
113    a[1]:=1;b[1]:=true;               //初始化,将整块板标为颜色1。
114 
115    readln(n,o,m);
116 
117     for i:=1 to m do
118 
119      begin
120 
121       read(c,sp);
122 
123       if c='C' then begin
124 
125                       readln(lc,rc,x);
126 
127                       if rc<lc then begin
128 
129                                      k:=rc;rc:=lc;lc:=k;
130 
131                                     end;
132 
133                       update(1,n,1);         
134 
135                     end
136 
137                else begin
138 
139                       readln(lc,rc);
140 
141                       if rc<lc then begin
142 
143                                      k:=rc;rc:=lc;lc:=k;
144 
145                                     end;
146 
147                       ans:=0;
148 
149                       query(1,n,1);
150 
151                       k:=0;
152 
153                       for j:=0 to o-1 do
154 
155                        if (ans shr j) and 1=1 then inc(k);   //查看二进制的数有多少位为1,即总共有多少种颜色。
156 
157                       writeln(k);
158 
159                     end;
160 
161      end;
162 
163   end;
164 
165 Begin
166 
167  assign(input,'poj2777.in');reset(input);
168 
169   init;
170 
171  close(input);
172 
173 end.

 

posted on 2016-03-02 17:34  Yesphet  阅读(176)  评论(0编辑  收藏  举报