Count Color
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
典型的线段树题目,唯一不同的是是查询区间内的元素的个数,我们可以利用颜色数目少的特性,利用二进制来枚举出所有的颜色,然后就是模板了
AC code:
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
using namespace std;
const int maxn = 1e5+10;
struct segtree{
int l,r,ans;
int lazy;
}ss[maxn<<2];
void build(int l,int r,int rt){
ss[rt].l = l,ss[rt].r = r;
if(l == r) {
ss[rt].ans = 1; ss[rt].lazy = 0;
return;
}
int mid = (l+r)>>1;
build(lson); build(rson);
ss[rt].lazy = 0; ss[rt].ans = 1;
}
void update (int l,int r,int rt,int val) {
if (ss[rt].l == l && ss[rt].r == r ) {
///printf("l = %d r = %d ss[rt].l = %d ss[rt].r = %d
",l,r,ss[rt].l,ss[rt].r);
ss[rt].ans = (1<<(val-1)); ss[rt].lazy = 1;
return;
}
if(ss[rt].lazy) {
ss[rt<<1].lazy = ss[rt<<1|1].lazy = 1;
ss[rt<<1].ans = ss[rt<<1|1].ans = ss[rt].ans;
ss[rt].lazy = 0;
}
int mid = (ss[rt].l+ss[rt].r)>>1;
if ( mid >= r ) {
update(l,r,rt<<1 ,val);
} else if ( mid < l ) {
update(l,r,rt<<1|1 , val);
} else {
update(lson ,val );
update(rson ,val);
}
ss[rt].ans = ss[rt<<1].ans | ss[rt<<1|1].ans;
}
int query(int l,int r,int rt){
if(l == ss[rt].l && r == ss[rt].r){
return ss[rt].ans;
}
if(ss[rt].lazy) {
ss[rt<<1].lazy = ss[rt<<1|1].lazy = 1;
ss[rt<<1].ans = ss[rt<<1|1].ans = ss[rt].ans;
ss[rt].lazy = 0;
}
int mid = (ss[rt].l+ss[rt].r)>>1; int sum = 0;
if ( mid >= r ) {
return sum | query(l ,r ,rt<<1 );
} else if ( mid < l ) {
return sum | query(l ,r ,rt<<1|1 );
} else {
return sum | query(lson ) | query(rson );
}
}
int main(){
int n,m,q,a,b,c;
while(scanf("%d %d %d",&n,&m,&q) != EOF){
build(1,n,1);
char str;
while(q--){
getchar();
scanf("%c",&str);
///printf("%c
",str);
if(str == 'C') {
scanf("%d %d %d",&a,&b,&c);
if(a>b) { int t = a; a = b; b = t; }
update(a,b,1,c);
} else if ( str == 'P' ) {
scanf("%d %d",&a,&b);
if(a>b) { int t = a; a = b; b = t; }
int sum = query(a,b,1),ans = 0;
while(sum){
if(sum&1) ans++;
sum>>=1;
}
printf("%d
",ans);
}
}
}
return 0;
}