Count Color POJ - 2777 (segment tree cover mark)

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

Meaning of the questions:
How many different colors in the dyeing operation, as well as seeking the interval
ideas: the
number of colors rarely be direct violence statistics.
Like "Ray, Pass me the dishes! " UVA - 1400 ( consolidated segment tree section)
maintain a cover mark represents the color of the range, it is initialized to 1.
Statistical when direct sweep this range, then vis array tag.

#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

const int maxn = 1e5 + 7;
int ans;
int vis[35];

struct Node
{
    int l,r;
    int cover;
}t[maxn << 2];

void pushup(int i)
{
    if(t[i * 2].cover == -1 || t[i * 2 + 1].cover == -1)
    {
        t[i].cover = -1;
    }
    else if(t[i * 2].cover == t[i * 2 + 1].cover)
    {
        t[i].cover = t[i * 2].cover;
    }
    else t[i].cover = -1;
}

void pushdown(int i)
{
    if(t[i].cover != -1)
    {
        t[i * 2].cover = t[i * 2 + 1].cover = t[i].cover;
    }
}

void build(int i,int l,int r)
{
    t[i].l = l;t[i].r = r;
    if(l == r)
    {
        t[i].cover = 1;
        return;
    }
    int m = (l + r) >> 1;
    build(i * 2,l,m);
    build(i * 2 + 1,m + 1,r);
    pushup(i);
}

void query(int i,int x,int y)
{
    if(t[i].cover != -1)
    {
        if(!vis[t[i].cover])
        {
            ans++;
            vis[t[i].cover] = 1;
        }
        return;
    }
    pushdown(i);
    int m = (t[i].l + t[i].r) >> 1;
    if(x <= m)
        query(i * 2,x,y);
    if(y > m)
        query(i * 2 + 1,x,y);
}

void update(int i,int x,int y,int v)
{
    if(x <= t[i].l && t[i].r <= y)
    {
        t[i].cover = v;
        return;
    }
    pushdown(i);
    int m = (t[i].l + t[i].r) >> 1;
    if(x <= m)update(i * 2,x,y,v);
    if(y > m )update(i * 2 + 1,x,y,v);
    pushup(i);
}

int main()
{
    int l,t,o;
    while(~scanf("%d%d%d",&l,&t,&o))
    {
        build(1,1,l);
        for(int i = 1;i <= o;i++)
        {
            char op[10];
            scanf("%s",op);
            if(op[0] == 'C')
            {
                int a,b,c;scanf("%d%d%d",&a,&b,&c);
                if(a > b)continue;
                update(1,a,b,c);
            }
            else if(op[0] == 'P')
            {
                int a,b;scanf("%d%d",&a,&b);
                ans = 0;
                memset(vis,0,sizeof(vis));
                query(1,a,b);
                printf("%d\n",ans);
            }
        }
    }
    return 0;
}


Published 628 original articles · won praise 17 · views 20000 +

Guess you like

Origin blog.csdn.net/tomjobs/article/details/104077007