POJ2777 Count Color线段树

Posted 海岛Blog

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ2777 Count Color线段树相关的知识,希望对你有一定的参考价值。

Count Color
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 62027 Accepted: 18419

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

问题链接POJ2777 Count Color
问题简述:一条长度为L的画板,有T种颜色,O个操作。每次操作将一个区间刷成一种颜色,或者查询一个区间内所含的颜色数量。
问题分析:线段树问题,不解释。
程序说明:(略)
参考链接:(略)
题记:(略)

AC的C++语言程序如下:

/* POJ2777 Count Color */

#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

const int N = 100000;
struct Tree {
    int l, r, c;
} t[N << 2];
int sum[30 + 1];

void buildTree(int n, int l, int r)
{
    t[n].l = l;
    t[n].r = r;
    t[n].c = 1;
    if (l != r) {
        int mid = (l + r) >> 1;
        buildTree(n << 1, l, mid);
        buildTree(n << 1 | 1, mid + 1, r);
    }
}

void update(int n, int l, int r, int m)
{
    if (t[n].c != m) {
        if (t[n].l == l && t[n].r == r)
            t[n].c = m;
        else {
            if (t[n].c != -1) {
                t[n << 1].c = t[n << 1 | 1].c = t[n].c;
                t[n].c = -1;
            }
            int mid = (t[n].l + t[n].r) >> 1;
            if (l > mid) update(n << 1 | 1, l, r, m);
            else if(r <= mid) update(n << 1, l, r, m);
            else {
                update(n << 1, l, mid, m);
                update(n << 1 | 1, mid + 1, r, m);
            }
        }
    }
}

void query(int n, int l, int r)
{
    if (t[n].c != -1) sum[t[n].c] = 1;
    else {
        int mid = (t[n].l + t[n].r) >> 1;
        if (l > mid)
            query(n << 1 | 1, l, r);
        else if (r <= mid)
            query(n << 1, l, r);
        else {
            query(n << 1, l, mid);
            query(n << 1 | 1, mid + 1, r);
        }
    }
}

int main()
{
    int l, t, o;
    while (scanf("%d%d%d", &l, &t, &o) == 3) {
        buildTree(1, 1, l);
        while (o--) {
            int a, b, c;
            char s[2];
            scanf("%s", s);
            if (s[0] == 'C') {
                scanf("%d%d%d", &a, &b, &c);
                update(1, a, b, c);
            } else if (s[0] == 'P') {
                memset(sum, 0, sizeof sum);
                int ans = 0;
                scanf("%d%d", &a, &b);
                query(1, a, b);
                for (int i = 1; i <= t; i++)
                    if (sum[i]) ans++;
                printf("%d\\n", ans);
            }
        }
    }

    return 0;
}

以上是关于POJ2777 Count Color线段树的主要内容,如果未能解决你的问题,请参考以下文章

POJ2777 Count Color线段树

POJ 2777 Count Color (线段树 + 状态压缩)

POJ P2777 Count Color——线段树状态压缩

POJ - 2777——Count Color(懒标记线段树二进制)

POJ训练计划2777_Count Color(线段树/成段更新/区间染色)

POJ 2777 Count Color (线段树成段更新+二进制思维)