简单的线段树,对区间染色查询,和zoj1610类似,代码如下:
#include<stdio.h>
#include<string.h>
#define MAXN 100000
struct Node{
int l ;
int r ;
int c ;
}tree[4*MAXN] ;
int ncount[35] ;
int l ;
int t ;
int o ;
void build(int l , int r , int c){
tree[c].c = 1 ;
tree[c].l = l ;
tree[c].r = r ;
if(l == r){
return ;
}
int mid = (l + r)/2 ;
build(l , mid , c * 2) ;
build(mid + 1 , r , c * 2 + 1) ;
}
void pushdown(int c){
if(tree[c].c < 1){
return ;
}
tree[c*2].c = tree[c].c ;
tree[c*2+1].c = tree[c].c ;
tree[c].c = 0 ;
}
void insert(int l , int r , int c , int color){
if(tree[c].c==color)
return ;
if(l==tree[c].l && r == tree[c].r){
tree[c].c = color ;
return ;
}
pushdown(c) ;
int mid = (tree[c].l + tree[c].r)/2 ;
if(r <= mid){
insert(l , r , c * 2 , color) ;
}
else if(l >= mid + 1){
insert(l , r , c * 2 + 1 , color) ;
}
else {
insert(l , mid , c * 2 , color) ;
insert(mid + 1 , r , c * 2 + 1 , color) ;
}
}
void query(int l , int r , int c){
if(tree[c].c >= 1){
ncount[tree[c].c] ++ ;
return ;
}
pushdown(c) ;
int mid = (tree[c].l + tree[c].r)/2 ;
if(r <= mid){
query(l , r , c*2) ;
}
else if(l >= mid + 1){
query(l , r , c * 2 + 1) ;
}
else{
query(l , mid , c * 2) ;
query(mid + 1 , r , c * 2 + 1) ;
}
}
bool work(){
if(scanf("%d %d %d" , &l , &t , &o)==EOF)
return 0 ;
char c ;
int i ;
int p ;
int q ;
int s ;
i = 0 ;
build(1 , l , 1) ;
while(i < o){
getchar() ;
scanf("%c" , &c) ;
if(c=='C'){
scanf("%d %d %d" , &p , &q , &s) ;
insert(p , q , 1 , s) ;
}
else{
scanf("%d %d" , &p , &q) ;
memset(ncount ,0 , sizeof(ncount)) ;
query(p , q , 1) ;
int num = 0 ;
int j ;
for(j = 1 ; j <= t ; j ++){
if(ncount[j])
num ++ ;
}
printf("%d\n" , num) ;
}
i++ ;
}
return 1 ;
}
int main(){
while(work())
;
return 0 ;
}