这里有一个思想:我们在更新的时候不必要更新到叶子节点,只要更新到当前区间包含线段树区间即可。
设计一个标志位,更新到此。
A Simple Problem with Integers 也是一个类似的题目
设计两个函数
push_down 将结点信息传递到下层节点(inc, sub,)
push_up 将下层节点信息反馈到上层(max,min,count)
#include <map> #include <set> #include <queue> #include <cmath> #include <cmath> #include <vector> #include <bitset> #include <vector> #include <cstdio> #include <cstdlib> #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define inf 0x3fffffff #define mid ((l+r)>>1) #define LSON(x) (x) << 1 #define RSON(x) (x) << 1 | 1 #define mem(x) memset(x,0,sizeof(x)) #define max(a,b) ((a)>(b)?(a):(b)) const int maxn=100+200000; const double eps=1e-6; typedef unsigned __int64 ull; vector< vector<int> > edge; #define lson l, m, rt << 1 #define rson m + 1, r, rt << 1 | 1 int sum[ maxn << 2 ], Add[ maxn << 2 ]; void PushUp( int rt ){ sum[ rt ] = ( sum[ rt << 1 ] | sum[ rt << 1 | 1 ] ); } void PushDown( int rt ){ if( Add[ rt ] != 0 ){ Add[ rt << 1 ] = Add[ rt << 1 | 1 ] = Add[ rt ]; sum[ rt << 1 ] = sum[ rt << 1 | 1 ] = sum[ rt ]; Add[ rt ] = 0; } } void Build( int l, int r, int rt ){ Add[ rt ] = 0; sum[ rt ] = 1; if( l == r ){ return; } int m = ( l + r ) >> 1; Build( lson ); Build( rson ); PushUp( rt ); } void Update( int L, int R, int temp, int l, int r, int rt ){ if( L <= l && r <= R ){ Add[ rt ] = 1; sum[ rt ] = temp; return; } PushDown( rt ); int m = ( l + r ) >> 1; if( L <= m ){ Update( L, R, temp, lson ); } if( R > m ){ Update( L, R, temp, rson ); } PushUp( rt ); } int Query( int L, int R, int l, int r, int rt ){ if( L == l && r == R ){ return sum[ rt ]; } PushDown( rt ); int m = ( l + r ) >> 1; int ans = 0; if( R <= m ) ans = Query( L, R, lson ); else if( L > m ) ans = Query( L, R, rson ); else ans = ( Query( L, m, lson ) | Query( m + 1, R, rson ) ); return ans; } //int _tmain(int argc, _TCHAR* argv[]) int main() { int n, m, k, a, b, c; char str[ 10 ]; while( scanf( "%d%d%d", &n, &m, &k ) != EOF ){ Build( 1, n, 1 ); while( k-- ){ scanf( "%s", str ); if( str[ 0 ] == 'C' ){ scanf( "%d%d%d", &a, &b, &c ); Update( a, b, 1 << ( c - 1 ), 1, n, 1 ); } else{ scanf( "%d%d", &a, &b ); if( a > b ) swap( a, b); int temp = Query( a, b, 1, n, 1 ); int ans = 0; while( temp ){ if( temp % 2 != 0 ) ans++; temp = ( temp >> 1 ); } printf( "%d\n", ans ); } } } return 0; }
POJ 2777 count color(线段树,lazy标记)
原文地址:http://blog.csdn.net/gg_gogoing/article/details/40260923