PKU 2777

PKU 2777

题型:线段树

描述:跟长为L的木棒的[a,b]段涂颜色,问[a1,b1]区间的不同颜色数。

 

思路:线段树的区间修改,“父节点控制子节点的思想”,当left = t[k].left && right = t[k].right 时更改 color域,并返回,不再修改其子节点的color值。

color = 0 表示当前区间有多种颜色,如果 [left, right]没有完全覆盖当前区间,则 t[2*k].color = t[2*k+1].color = t[k].color; t[k].color = 0; 即,

将子节点的颜色值改为父节点的颜色值,父节点的颜色值置为 0 。

 

心得:

1.刚开始写的很不熟练,错误百出,后参考了笑风生的博客,发现很喜欢其代码风格,于是学习了一下。

2.关于数组开多大,令NL 取 大于L 的 2^k数。

 

代码
   
     
// key 1第一次都写成了 [left, mid]或 [mid, right]
// key 2为关键之处,借鉴于笑风生
// 4244K 344MS
#include < stdio.h >
#include
< string .h >
#define SWP(x,y,t) ((t)=(x),(x)=(y),(y)=(t))
#define NL 131072

struct Seg {
int l, r, md;
int clr;
}t[NL
* 2 ];
bool flg[ 31 ];
int cnt;

void build( int l, int r, int k)
{
t[k].l
= l;
t[k].r
= r;
t[k].md
= (l + r) / 2 ;
if (l + 1 < r) {
build(l, t[k].md, k
* 2 );
build(t[k].md, r, k
* 2 + 1 );
}
}

void mody( int l, int r, int k, int clr)
{
if (t[k].l == l && t[k].r == r) {
t[k].clr
= clr;
return ;
}
if (t[k].clr > 0 ) { // key 2
t[ 2 * k].clr = t[ 2 * k + 1 ].clr = t[k].clr;
t[k].clr
= 0 ;
}
if (r <= t[k].md) mody(l, r, k * 2 , clr); // key 1
else if (l >= t[k].md) mody(l, r, k * 2 + 1 , clr); // key 1
else {
mody(l, t[k].md, k
* 2 , clr);
mody(t[k].md, r, k
* 2 + 1 , clr);
}
}

void count( int l, int r, int k) {
if (t[k].clr) { // key 2
flg[t[k].clr] = 1 ;
return ;
}
if (r <= t[k].md)
count(l, r, k
* 2 ); // key 1
else if (l >= t[k].md)
count(l, r, k
* 2 + 1 ); // key 1
else {
count(l, t[k].md, k
* 2 );
count(t[k].md, r, k
* 2 + 1 );
}
}

int main()
{
int L, T, O, i, j;
int a, b, c, tmp;
char s[ 3 ];
while (scanf( " %d%d%d " , & L, & T, & O) != EOF) {
build(
1 , L + 1 , 1 );
t[
1 ].clr = 1 ;
for (i = 0 ; i < O; i ++ ) {
scanf(
" %s " , s);
if (s[ 0 ] == ' C ' ) {
scanf(
" %d%d%d " , & a, & b, & c);
if (a > b) SWP(a,b,tmp);
mody(a, b
+ 1 , 1 , c);
}
else {
scanf(
" %d%d " , & a, & b);
if (a > b) SWP(a,b,tmp);
memset(flg,
0 , sizeof (flg));
cnt
= 0 ;
count(a, b
+ 1 , 1 );
for (j = 1 ; j <= T; j ++ ) {
if (flg[j]) cnt ++ ;
}
printf(
" %d\n " , cnt);
}
}
}
return 0 ;
}

 

 

你可能感兴趣的:(pku)