Count Color(线段树+位运算 POJ2777)

Count Color
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 39917 Accepted: 12037

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,明明是(1<<1).悲哀啊

#include <map>
#include <set>
#include <queue>
#include <cstring>
#include <string>
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
struct node
{
    int sta;
    bool lazy;
}Tree[500000];
int Trans(int ans)
{
    int sum=0;
    while(ans)
    {
        if(ans&1)
        {
            sum++;
        }
        ans/=2;
    }
    return sum;
}
void Build(int L,int R,int site)
{
    Tree[site].lazy=false;
    Tree[site].sta=2;//初始化为颜色1就是(1<<1),看了一晚上才看出来
    if(L==R)
    {
        return ;
    }
    int mid=(L+R)>>1;
    Build(L,mid,site<<1);
    Build(mid+1,R,site<<1|1);
}
void update(int L,int R,int l,int r,int site,int ans)
{
    if(L==l&&R==r)//更新到区间
    {
        Tree[site].sta=(1<<ans);
        Tree[site].lazy=true;
        return ;
    }
    if(Tree[site].lazy)//向下更新
    {
        Tree[site<<1].sta=Tree[site<<1|1].sta=Tree[site].sta;
        Tree[site<<1].lazy=Tree[site<<1|1].lazy=true;
        Tree[site].lazy=false;
    }
    int mid=(L+R)>>1;
    if(r<=mid)
    {
        update(L,mid,l,r,site<<1,ans);
    }
    else if(l>mid)
    {
        update(mid+1,R,l,r,site<<1|1,ans);
    }
    else
    {
        update(L,mid,l,mid,site<<1,ans);
        update(mid+1,R,mid+1,r,site<<1|1,ans);
    }
    Tree[site].sta=Tree[site<<1].sta|Tree[site<<1|1].sta;//区间的合并
}

int Query(int L,int R,int l,int r,int site)
{
    if(L==l&&R==r)
    {
        return Tree[site].sta;
    }
    if(Tree[site].lazy)//向下更新
    {
        Tree[site<<1].sta=Tree[site<<1|1].sta=Tree[site].sta;
        Tree[site<<1].lazy=Tree[site<<1|1].lazy=true;
        Tree[site].lazy=false;
    }
    int mid=(L+R)>>1;
    if(r<=mid)
    {
        return Query(L,mid,l,r,site<<1);
    }
    else if(l>mid)
    {
        return Query(mid+1,R,l,r,site<<1|1);
    }
    else
    {
        return Query(L,mid,l,mid,site<<1)|Query(mid+1,R,mid+1,r,site<<1|1);
    }
}
int main()
{
    int L,T,O;
    char s[3];
    int a,b,c;
    while(~scanf("%d %d %d",&L,&T,&O))
    {
        Build(1,L,1);
        for(int i=1;i<=O;i++)
        {
            scanf("%s %d %d",s,&a,&b);
            if(a>b)
            {
                swap(a,b);
            }
            if(s[0]=='C')
            {
                scanf("%d",&c);
                update(1,L,a,b,1,c);
            }
            else
            {
                int ans=Query(1,L,a,b,1);
                ans=Trans(ans);
                printf("%d\n",ans);
            }
        }
    }
    return 0;
}
posted @ 2015-09-04 20:28  一骑绝尘去  阅读(169)  评论(0编辑  收藏  举报