您的位置:首页 > 其它

poj 2777 Count Color

2013-07-18 11:36 253 查看
题目链接:http://poj.org/problem?id=2777

题意:有一根长为L的木板,有两种对木板的操作,一种是把一段木板[a, b]涂成一种颜色,另一种操作是求木板段[a, b]中共有多少种颜色。其中颜色有T种, 木板默认的颜色是颜色1.

方法:线段树,这个道题的技巧是要用到位操作,因为颜色最多有30种。其中要用到Lazy-Tag的思想。

代码如下:

#include <iostream>
#include <cstdio>
#define MAX 100001
using namespace std;
struct node
{
int l, r, color;
bool flag;
}v[5*MAX];

void pushup(int n)
{
v
.color = v[2*n].color | v[2*n+1].color;
}
void pushdown(int n)
{
if (v
.flag)
{
v[2*n].flag = true;
v[2*n+1].flag = true;
v[2*n].color = v
.color;
v[2*n+1].color = v
.color;
v
.flag = false;
}
}
void build(int l, int r, int n)
{
v
.l = l;
v
.r = r;
v
.flag = false;
if (l == r)
{
v
.color = 1;
return ;
}
int mid = (l+r)/2;
build(l, mid, 2*n);
build(mid+1, r, 2*n+1);
pushup(n);
}
void update(int l, int r, int d, int n)
{
if (l<=v
.l && v
.r<=r)
{
v
.flag = true;
v
.color = 1<<(d-1);
return ;
}
pushdown(n);
int mid = ( v
.l + v
.r )/2;
if (r<=mid)
update(l, r, d, 2*n);
else if (l > mid)
update(l, r, d, 2*n+1);
else
{
update(l, mid, d, 2*n);
update(mid+1, r, d, 2*n+1);
}
pushup(n);
}
int query(int l, int r, int n)
{
if (l<=v
.l && v
.r<=r)
return v
.color;
pushdown(n);
int mid = (v
.l + v
.r)/2;
if (r <= mid)
return query(l, r, 2*n);
else if (l > mid)
return query(l, r, 2*n+1);
else
return query(l, mid, 2*n) | query(mid+1, r, 2*n+1);
}
int main()
{
int L, T, O, a, b, c;
char ch;
while (~scanf("%d%d%d", &L, &T, &O))
{
build(1, L, 1);
while (O--)
{
getchar();
scanf("%c", &ch);
if (ch == 'C')
{
scanf("%d %d %d", &a, &b, &c);
if (a<b)
update(a, b, c, 1);
else
update(b, a, c, 1);
}
else
{
scanf("%d %d", &a, &b);
int t;
if (a < b)
t = query(a, b, 1);
else
t = query(b, a, 1);
int len = 0;
for(int i=0; i<T; i++)
if(t & (1<<i))
len++;
printf("%d\n", len);
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: