题目分析:用线段树解决,每次update时,记录更新的区间的长度即可。很久以前不会写,今天一看,顿时灵光一闪,水题啊!
代码如下:
#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std ;
#define REP( i , a , b ) for ( int i = ( a ) ; i < ( b ) ; ++ i )
#define FOR( i , a , b ) for ( int i = ( a ) ; i <= ( b ) ; ++ i )
#define REV( i , a , b ) for ( int i = ( a ) ; i >= ( b ) ; -- i )
#define CLR( a , x ) memset ( a , x , sizeof a )
#define ls ( o << 1 )
#define rs ( o << 1 | 1 )
#define lson ls , l , m
#define rson rs , m + 1 , r
#define root 1 , 1 , 100000
#define rt o , l , r
#define mid ( ( l + r ) >> 1 )
const int MAXN = 100005 ;
int maxv[MAXN << 2] , same[MAXN << 2] , set[MAXN] ;
void pushup ( int o ) {
maxv[o] = max ( maxv[ls] , maxv[rs] ) ;
same[o] = ( same[ls] == same[rs] ? same[ls] : 0 ) ;
}
void pushdown ( int o ) {
if ( set[o] ) {
maxv[ls] = maxv[rs] = set[o] ;
same[ls] = same[rs] = set[o] ;
set[ls] = set[rs] = set[o] ;
set[o] = 0 ;
}
}
int update ( int L , int R , int v , int o , int l , int r ) {
if ( same[o] > v ) return 0 ;
if ( L <= l && r <= R ) {
if ( v >= maxv[o] ) {
maxv[o] = same[o] = set[o] = v ;
return r - l + 1 ;
}
}
pushdown ( o ) ;
int m = mid , ans = 0 ;
if ( L <= m ) ans += update ( L , R , v , lson ) ;
if ( m < R ) ans += update ( L , R , v , rson ) ;
pushup ( o ) ;
return ans ;
}
void solve () {
int n , l , r , h ;
int ans = 0 ;
scanf ( "%d" , &n ) ;
CLR ( maxv , 0 ) ;
CLR ( same , 0 ) ;
CLR ( set , 0 ) ;
while ( n -- ) {
scanf ( "%d%d%d" , &l , &r , &h ) ;
ans += update ( l , r - 1 , h , root ) ;
}
printf ( "%d\n" , ans ) ;
}
int main () {
int T ;
scanf ( "%d" , &T ) ;
while ( T -- ) solve () ;
return 0 ;
}
本文介绍了一种使用线段树解决UVALive 4108 SKYLINE问题的方法。通过记录区间长度进行更新操作,实现高效求解。代码示例展示了如何初始化线段树,并提供了解决方案的具体实现。
1650

被折叠的 条评论
为什么被折叠?



