这里有一个思想:我们在更新的时候不必要更新到叶子节点,只要更新到当前区间包含线段树区间即可。
设计一个标志位,更新到此。
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