码迷,mamicode.com
首页 > 其他好文 > 详细

Uva 1232 - SKYLINE ( 线段树 + 区间更新 )

时间:2014-09-24 22:57:57      阅读:263      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   color   io   os   ar   strong   for   

 

Uva 1232 SKYLINE (线段树 + 区间更新)

题意: 按照顺序在地面上建造放在,每个房子的高度为h,操作 l r h 表示 在(l,r] 区间建立一个高度为h的房子。
统计每次建立完房子之后的overlap值之和

overlap值表示[ 修完一座房子之后,统计它在多长的部分是最高的(可以和其他房子并列高) ]
如样例图,按照灰、黒。白的顺序建立房子
ans = (11-5) + (5-1) + (5-3) + (13-11) = 6 + 4 + 4 = 14

bubuko.com,布布扣


分析: 一开始一直想不明白如何向下传递,这里实际上Pushdown操作就是普通的懒惰标记
PushUp操作用来想上更新minh和maxh

这里需要维护至少两个域 一个是 房子的高度setv 一个是maxh,区间内房子的最大高度。
不过从别人的博客看到还有一个优化,就是再开一个minh域,存放区间内房子的最小高度,
很显然,如果新建立的房子高度比该区间的minh还小,就不需要更新了。
结果用ans进行累加即可,这里要注意,线段是连续的,但是所以区间(l,r]想当于[l+1,r]
update的时候注意下,还有就是求ans的时候记得+1

bubuko.com,布布扣
//#define BUG
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
#include <vector>
#include <list>
#include <queue>
#include <ctime>
#include <iostream>
#include <cmath>
#include <set>
#include <string>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
#define INF                 0x7fffffff
#define MAX                 0x3f3f3f3f

#define CLR( a, b )         memset( a, b, sizeof(a) )
#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 FOD( i, a, b )      for( int i = (a); i >=(b); --i )

#define MID                 ( l + r ) >> 1
#define lson                l, m, o << 1
#define rson                m + 1, r, o << 1 | 1
#define ls                  o << 1
#define rs                  o << 1 | 1
#define MAXN                100010

struct SegTree
{
    int l, r;
    int setv, maxh, minh;

}tree[MAXN << 2];
int ans;

void PushUp( int o )
{
    tree[o].maxh = max( tree[ls].maxh , tree[rs].maxh );
    tree[o].minh = min( tree[ls].minh , tree[rs].minh );
}

void PushDown( int o )
{
    if( tree[o].setv != -1 )        //三个标记往下传
    {
        tree[ls].setv = tree[rs].setv = tree[o].setv;
        tree[ls].maxh = tree[rs].maxh = tree[o].maxh;
        tree[ls].minh = tree[rs].minh = tree[o].minh;
        tree[o].setv = -1;
    }
}

void Build( int l, int r, int o )
{
    tree[o].l = l, tree[o].r = r;
    tree[o].setv = tree[o].maxh = tree[o].minh = 0;
    if( l == r )
        return;
    int m = MID;
    Build( lson );
    Build( rson );
}


void Update( int L, int R, int c, int o )
{
    if( tree[o].minh > c )    return;
    if( tree[o].l == L && tree[o].r == R )
    {
        if( tree[o].maxh <= c )
        {
            tree[o].setv = tree[o].maxh = tree[o].minh = c;
            ans += R - L + 1;
            return;
        }
        if( L == R )  return;
    }

    PushDown( o );
    int m = ( tree[o].l + tree[o].r ) >> 1;
    if( R <= m )  Update( L, R, c, ls );
    else if( L >  m )  Update( L, R, c, rs );
    else
    {
        Update( L, m, c, ls );
        Update( m + 1, R, c, rs );
    }
    PushUp( o );
}

void Orz()
{
    #ifdef  BUG
        freopen("in.txt","r",stdin);
    #endif
    int cas, n;
    int l, r, c;
    while( ~scanf( "%d", &cas ) && cas )
    {
        while( cas-- )
        {
            scanf( "%d", &n );
            Build(1,MAXN,1);
            ans = 0;
            while( n-- )
            {
                scanf( "%d %d %d", &l, & r, &c );
                Update( l + 1, r, c, 1);
            }
            printf( "%d\n", ans );
        }
    }
}

int main()
{
    Orz();
    return 0;
}
代码君

 

 

 








Uva 1232 - SKYLINE ( 线段树 + 区间更新 )

标签:style   blog   http   color   io   os   ar   strong   for   

原文地址:http://www.cnblogs.com/BigBallon/p/3991491.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!