pku2777 线段树 (位运算加速)

Count Color

有三个关键点,前两个和hdu1698一样

key1:记得将区间覆盖值置0时,将区间值赋给它的两个子区间

key2:当前区间cover不为0,即可return

key3:数据比较小,用位运算或操作,进行集合合并,加速过程。

 

ContractedBlock.gif ExpandedBlockStart.gif 代码
 
   
#include < stdio.h >
#include
< stdlib.h >
#define NN 100000
struct node{
int l, r, mid, cover;
}seg_tree[NN
* 8 ];

void Init( int l, int r, int id){
seg_tree[id].l
= l;
seg_tree[id].r
= r;
seg_tree[id].mid
= (l + r) >> 1 ;
seg_tree[id].cover
= 1 ;

if (r - l <= 1 ){
return ;
}

Init(l, seg_tree[id].mid, id
* 2 );
Init(seg_tree[id].mid, r, id
* 2 + 1 );
}

void Update( int l, int r, int key, int id){
if (seg_tree[id].l == l && seg_tree[id].r == r){
seg_tree[id].cover
= key;
return ;
}
// key 1
if (seg_tree[id].cover != 0 ){
seg_tree[id
* 2 ].cover = seg_tree[id].cover;
seg_tree[id
* 2 + 1 ].cover = seg_tree[id].cover;
seg_tree[id].cover
= 0 ;
}

if (r <= seg_tree[id].mid){
Update(l, r, key, id
* 2 );
}
else if (l >= seg_tree[id].mid){
Update(l, r, key, id
* 2 + 1 );
}
else {
Update(l, seg_tree[id].mid, key, id
* 2 );
Update(seg_tree[id].mid, r, key, id
* 2 + 1 );
}
}

int Search( int l, int r, int id){
// key 2
if (seg_tree[id].cover > 0 ){
return 1 << seg_tree[id].cover;
}

if (r <= seg_tree[id].mid){
return Search(l, r, id * 2 );
}
else if (l >= seg_tree[id].mid){
return Search(l, r, id * 2 + 1 );
}
else {
return Search(l, seg_tree[id].mid, id * 2 ) | Search(seg_tree[id].mid, r, id * 2 + 1 ); // key 3
}
}
int main(){
int L, T, O, a, b, c, cnt, ans;
char str[ 3 ];
scanf(
" %d%d%d " , & L, & T, & O);
Init(
0 , L, 1 );
while (O -- ){
scanf(
" %s " , str);
if (str[ 0 ] == ' C ' ){
scanf(
" %d%d%d " , & a, & b, & c);
Update(a
- 1 , b, c, 1 );
}
else {
scanf(
" %d%d " , & a, & b);
ans
= Search(a - 1 , b, 1 );
cnt
= 0 ;
while (ans){
cnt
+= ans % 2 ;
ans
/= 2 ;
}
printf(
" %d\n " , cnt);
}
}
// system("pause");
}

 

 

 

转载于:https://www.cnblogs.com/ylfdrib/archive/2010/07/17/1779913.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值