POJ - 2227 Count Color

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\n",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\n",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\n",ans);
            }
        }
    }

    return 0;
}

猜你喜欢

转载自blog.csdn.net/Acer12138/article/details/81327609