POJ 2777-Count Color(線段樹-區間染色查詢)
Count Color
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 45268 | Accepted: 13705 |
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.
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
題目意思:
L長的木板染上T種顏色,有O個操作,其中C a b c表示a~b長度區間全部染成c這種顏色,Q a b表示查詢區間a~b內不同顏色的個數。
解題思路:
線段樹節點儲存該區間內的顏色,單點區間肯定就是染成的顏色,大區間如果標記為-1則表示該區間由多種顏色的小區間組成,注意初始情況下木板均為同一種顏色,可以記為1。
一共有最多30種顏色,所以用bool vis[30]陣列標記,在每次查詢的時候清空,查詢到點或區間顏色相同時,對該顏色標記為true,最後統計1~T這T種顏色使用的個數即vis是true的情況。
#include<iostream>
#include<cstdio>
#include<iomanip>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<map>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
#define INF 0xfffffff
#define MAXN 275000
bool vis[50];//1表示該區間有該顏色
int ans[MAXN*4];
struct Node //樹
{
int l,r;//左右節點
int col;//區間內的顏色
};
Node tree[MAXN*5];
void BuildTree(int root, int l, int r)//建樹
{
tree[root].l=l;
tree[root].r=r;
tree[root].col=1;//初始狀態都是同一種顏色
if(l!=r)
{
BuildTree(2*root,l,(l+r)/2);
BuildTree(2*root+1,(l+r)/2+1,r);
}
}
void Insert(int i,int l,int r,int c)//插入
{
if(tree[i].col==c)//同色
return ;
if(tree[i].l==l&&tree[i].r==r)
{
tree[i].col=c;//染色
return ;
}
if(tree[i].col!=-1)//同色
{
tree[2*i].col=tree[2*i+1].col=tree[i].col;
tree[i].col=-1;
}
int mid=(tree[i].l+tree[i].r)/2;
if(r<=mid)
Insert(2*i,l,r,c);
else if(l>mid)
Insert(2*i+1,l,r,c);
else
{
Insert(2*i,l,mid,c);
Insert(2*i+1,mid+1,r,c);
}
}
void Query(int i,int l,int r)
{
if(tree[i].col!=-1)//同色
{
vis[tree[i].col]=true;
return;
}
int mid=(tree[i].l+tree[i].r)/2;
if(r<=mid)
Query(2*i,l,r);
else if(l>mid)
Query(2*i+1,l,r);
else
{
Query(2*i,l,mid);
Query(2*i+1,mid+1,r);
}
}
int main()
{
#ifdef ONLINE_JUDGE
#else
freopen("G:/cbx/read.txt","r",stdin);
//freopen("G:/cbx/out.txt","w",stdout);
#endif
int l,t,n;
scanf("%d%d%d\n",&l,&t,&n);
//while(~scanf("%d%d%d\n",&l,&t,&n))
{
BuildTree(1,1,n);//建樹
while(n--)
{
char ch;
cin>>ch;
if(ch=='C')
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
if(a>b) swap(a,b);//如果a>b
Insert(1,a,b,c);
}
else if(ch=='P')
{
memset(vis,false,sizeof(vis));
int a,b,ans=0;
scanf("%d%d",&a,&b);
if(a>b) swap(a,b);
Query(1,a,b);
for(int i=1; i<=t; ++i)
if(vis[i]) ++ans;
printf("%d\n",ans);
}
}
}
return 0;
}
相關文章
- POJ 3468 【區間修改+區間查詢 樹狀陣列 | 線段樹 | 分塊】陣列
- 芻議線段樹 2 (區間修改,區間查詢)
- POJ 3468 A Simple Problem with Integers(線段樹區間操作)
- POJ 3468 A Simple Problem with Integers (線段樹 區間更新)
- POJ 2777 Count Color 線段樹入門題
- POJ 3468 A Simple Problem with Integers (線段樹 區間共加)
- POJ 3468-A Simple Problem with Integers(區間更新線段樹)
- 線段樹(1)建樹、單點修改、單點查詢、區間查詢和例題
- 1082 線段樹練習 3 區間查詢與區間修改
- poj 3237 樹鏈剖分(區間更新,區間查詢)
- HDU1698 Just a Hook【線段樹基礎:區間修改+區間查詢】Hook
- POJ 2528 Mayor's posters (線段樹 區間更新+離散化)
- POJ 2528 Mayor's posters (線段樹區間更新 + 離散化)
- HDU1754 I Hate It 【線段樹基礎:點修改+區間查詢】
- 1080 線段樹練習 單點修改及區間查詢
- POJ 3264 Balanced Lineup 線段樹入門(點的查詢)
- 1081 線段樹練習 2 單點查詢及區間修改
- hihocoder 1078 線段樹的區間修改 (線段樹 區間更新 模板)
- POJ 3264-Balanced Lineup詳解(線段樹區間求值)
- 線段樹維護單調棧——區間查詢版本 & 維護遞減序列
- HDU 1556-Color the ball(樹狀陣列-區間修改 單點查詢)陣列
- POJ 1195-Mobile phones(二維樹狀陣列-區間更新區間查詢)陣列
- HDU 1556 Color the ball(線段樹|樹狀陣列)陣列
- 線段樹(3)——區間操作疊加
- HDU1166 敵兵佈陣【線段樹基礎:點修改+區間查詢】
- 【樹狀陣列 區間更新區間查詢】code陣列
- POJ 2155-Matrix(二維樹狀陣列-區間修改 單點查詢)陣列
- HDU 1556 Color the ball 線段樹入門題
- 線段樹維護區間等差數列
- hdu 1394 Minimum Inversion Number 【線段樹查詢】
- 樹狀陣列的區間查詢與區間修改陣列
- HDU 1754 I Hate It (線段樹 區間最值)
- Java 演算法-區間求和I(線段樹)Java演算法
- HDU 1698 Just a Hook (線段樹區間更新)Hook
- Codeforces 52C (線段樹區間更新)
- 區間k小值(可持久化線段樹)持久化
- POJ 2991 Crane(線段樹+計算幾何)
- JPA時間段查詢