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:
- “C A B C” Color the board from segment A to segment B with color C.
- “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
问题链接: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线段树的主要内容,如果未能解决你的问题,请参考以下文章
POJ 2777 Count Color (线段树 + 状态压缩)
POJ P2777 Count Color——线段树状态压缩
POJ - 2777——Count Color(懒标记线段树二进制)