POJ 2777 Count Color (线段树、lazy思想)
2013-10-05 20:04
323 查看
题意:有一个区间,最多有30种颜色。有两种操作,一种是对某一个区间段染上某一种颜色,一种是询问该区间有多少种不同的颜色。
思路:线段树的好题,线段树 + lazy思想的经典应用。而且和位运算结合到了一起。因为颜色数量很少,而且父结点的颜色正好是两个子结点颜色的按位或,因此可以用位运算。最后1的个数就是不同颜色的个数。
思路:线段树的好题,线段树 + lazy思想的经典应用。而且和位运算结合到了一起。因为颜色数量很少,而且父结点的颜色正好是两个子结点颜色的按位或,因此可以用位运算。最后1的个数就是不同颜色的个数。
// 4276K 297MS #include <cstdio> #include <iostream> #include <cstring> #define MID(X,Y) ((X+Y)>>1) #define L(X) ((X)<<1) #define R(X) (((X)<<1)|1) #define MAX 100050 using namespace std ; struct Node { int l , r ; int col ; //用一个32位的int型,每一位对应一种颜色(例将1转换成 00000...1 ,2转换成000...10, 每个共32位),用位运算代替bool col[32] bool cover ; //cover =ture 表示该区间染上同一种颜色,否则表示染上的颜色为混合色 }node[3*MAX]; void swap ( int & a , int & b ) { int temp ; temp = a ; a = b ; b = temp ; } void BuildTree ( int const left , int const right , int const n ) { node .l = left ; node .r = right ; node .col = 1 ; node .cover = true ; if ( node .l == node .r ) { return ; } else { int mid ; mid = MID(node .l,node .r ) ; BuildTree ( left , mid , L(n) ) ; BuildTree ( mid + 1 , right , R(n) ) ; } return ; } void Delay_Update ( int const n ) { int value ; value = node .col ; node .cover = false ; node[L(n)].col = value ; node[L(n)].cover = true ; node[R(n)].col = value ; node[R(n)].cover = true ; } void Update ( int const left , int const right , int const value , int const n ) { if ( left <= node .l && right >= node .r ) { node .col = value ; node .cover = true ; return ; } else { if ( node .col == value ) //剪枝 { return ; } else { if ( node .cover ) { Delay_Update ( n ) ; } int mid ; mid = MID ( node .l , node .r ) ; if ( right <= mid ) { Update ( left , right , value , L(n) ) ; } else if ( left > mid ) { Update ( left , right , value , R(n) ) ; } else { Update ( left , mid , value , L(n) ) ; Update ( mid + 1 , right , value , R(n) ) ; } node .col = node[L(n)].col | node[R(n)].col ; } } } void Query ( int const left , int const right , int & sum , int const n ) { if ( node .cover ) { sum |= node .col ; return ; } else if ( left <= node .l && right >= node .r ) { sum |= node .col ; return ; } else { int mid ; mid = MID (node .l , node .r ) ; if ( right <= mid ) { Query ( left , right , sum , L(n) ) ; } else if ( left > mid ) { Query ( left , right , sum , R(n) ) ; } else { Query ( left , mid , sum , L(n) ) ; Query ( mid + 1 , right , sum , R(n) ) ; } } return ; } int Get_Answer ( int sum ) //找出sum中"1"的个数 { int ans ; ans = 0 ; while ( sum ) { if ( sum % 2 ) { ans ++ ; } sum = sum >> 1 ; } return ans ; } int main ( ) { int L,T,O ;//L代表board长度,T代表color种类,O代表总操作数 scanf ("%d%d%d" , & L , & T , & O ) ; BuildTree ( 1 , L , 1 ) ; while ( O-- ) { getchar ( ) ; //吃掉回车 char oper ; scanf ("%c" , & oper ) ; if ( 'C' == oper ) { int left , right ; int k ; //k代表要更新的第k中颜色 scanf ("%d%d%d" , & left , & right , & k ) ; int trans ; trans = 1 << ( k - 1 ) ; //将k在表示上转换成与node .col对应的形式 Update ( left , right , trans , 1 ) ; } else { int left , right ; scanf ("%d%d" , & left , & right ) ; if ( right < left ) { swap ( left , right ) ; } int sum ; sum = 0 ; Query ( left , right , sum , 1 ) ; int ans ; ans = Get_Answer ( sum ) ; printf ("%d\n" , ans ) ; } } return 0 ; }
相关文章推荐
- poj 2777 Count Color(线段树 Lazy-Tag思想 成段更新+区间统计)
- POJ 2777 Count Color(线段树、lazy思想)
- poj(2777)——Count Color(lazy思想,成段更新,区间统计)
- POJ 2777 Count Color (线段树的区间更新+lazy tag)
- POJ 2777 count color(线段树,lazy标记)
- 【线段树(lazy)】poj 2777 Count Color
- [poj] 2777 - Count Color - 线段树 + 状态压缩思想(?)
- POJ 2777 Count Color 线段树区间更新位运算
- POJ-2777 Count Color(线段树,区间染色问题)
- poj 2777 Count Color(线段树)
- poj_2777 Count Color(线段树染色)
- POJ 2777 Count Color (线段树)
- POJ 2777 Count Color(线段树)
- poj 2777 Count Color(线段树)
- hdoj 2777 Count Color 【线段树lazy区间染色 + 查询区间颜色数目 + 状态压缩】
- POJ 2777 Count Color 线段树
- POJ 2777 Count Color 线段树区间更新位运算
- POJ 2777 Count Color 线段树 成段更新
- poj 2777 染色线段树 count color
- poj 2777 Count Color(线段树区间更新)