//关键点:
//1. 用位代表颜色,计算某个段的颜色组成时,用或运算:
// line[c].color = line[c<<1].color | line[(c<<1)+1].color
//2. 延时着色,即当某一层为纯色时,则将它的子节点都标记为该颜色
#include <iostream>
using namespace std;
struct node{
int from, to;
//每一位代表一种color,而且有如下关系式
//line[c].color = line[c<<1].color | line[(c<<1)+1].color
int color;
};
const int MAX_NUM = 100002;
node line[3*MAX_NUM];
//建树
void build_tree(int from, int to, int c)
{
line[c].from = from;
line[c].to = to;
line[c].color = 1;
if (from == to) return;
int mid = (from + to) / 2;
build_tree(from, mid, c<<1);
build_tree(mid+1, to, (c<<1)+1);
}
int paint(int from, int to, int color, int c)
{
//使用了延时着色,因为
//如果是if (line[c].from == line[c].to)则超时
if (line[c].from == from && line[c].to == to){
line[c].color = color;
}
else {
//延时着色,即当某一层为纯色时,则将它的子节点都标记为该颜色
if (((line[c].color) & (line[c].color-1)) == 0){
line[c<<1].color = line[(c<<1)+1].color = line[c].color;
}
int mid = line[c<<1].to;
if (from > mid){
line[c].color = line[c<<1].color
| paint(from, to, color, (c<<1)+1);
}
else{
if (to > mid){
line[c].color = paint(from, mid, color, c<<1)
| paint(mid+1, to, color, (c<<1)+1);
}
else{
line[c].color = paint(from, to, color, c<<1)
| line[(c<<1)+1].color;
}
}
}
return line[c].color;
}
int query (int from, int to, int c)
{
if (line[c].from == from && line[c].to == to){
return line[c].color;
}
if (((line[c].color) & (line[c].color-1)) == 0){ //延时着色
line[c<<1].color = line[(c<<1)+1].color = line[c].color;
}
int mid = line[c<<1].to;
if (from > mid){
return query(from, to, (c<<1)+1);
}
else{
if (to > mid){
return query(from, mid, c<<1) | query(mid+1, to, (c<<1)+1);
}
else{
return query(from, to, c<<1);
}
}
}
inline void swap(int& a, int &b)
{
a = a ^ b;
b = a ^ b;
a = a ^ b;
}
int main()
{
int L, T, O, i, A, B, C, cnt;
char opt;
scanf("%d%d%d", &L, &T, &O);
build_tree(1, L, 1);
for (i = 0; i < O; ++i){
cin>>opt;
if (opt == 'C'){
scanf("%d%d%d", &A, &B, &C);
if (A > B) swap(A, B);
paint(A, B, 1<<(C-1), 1);
}
else{
scanf("%d%d", &A, &B);
if (A > B) swap(A, B);
C = query(A, B, 1);
cnt = 0;
while (C){
cnt++;
C &= (C-1);
}
printf("%d\n", cnt);
}
}
return 0;
}
POJ 2777 (线段树)
最新推荐文章于 2019-08-07 17:14:00 发布