P1904 天际线(线段树)

题目传送门

天际线

题目大意

在二维坐标系的第一象限中,x轴上有多个城市,分别给你每个高楼的起始点,高度和终止点,高楼可以重叠,求高楼的总轮廓,输出为每个折点的(x,y)

思路

做法:扫描线+线段树做线段区间覆盖
数据范围不大,所以可以不离散化
直接线段树维护区间最大值即可

AC Code

#include<bits/stdc++.h>
using namespace std;
const int N=1e4+7;
int t[N<<2],tag[N<<2];
inline int lc(int p)    {return p<<1;}
inline int rc(int p)    {return p<<1|1;}
inline void push_up(int p)  {t[p]=max(t[lc(p)], t[rc(p)]);}
inline void f(int p, int k){
    t[p]=max(t[p], k);
    tag[p]=max(tag[p], k);
}
inline void push_down(int p){
    f(lc(p), tag[p]);
    f(rc(p), tag[p]);
    tag[p]=0;
}
inline void updata(int p, int l, int r, int x, int y, int k){
    if(x>r || y<l)  return ;
    if(l<=x && y<=r){
        t[p]=max(t[p],k);
        tag[p]=max(tag[p],k);
        return ;
    }  
    int mid=(x+y)>>1;
    if(tag[p])  push_down(p);
    updata(lc(p), l, r, x, mid, k);
    updata(rc(p), l, r, mid+1, y, k);
    push_up(p);
}
inline int query(int p, int l, int r, int x, int y){
    if(x>r || y<l)  return 0;
    if(l<=x && y<=r) return t[p];
    int mid=(x+y)>>1;
    if(tag[p])  push_down(p);
    return max(query(lc(p), l, r, x, mid), query(rc(p), l, r, mid+1, y));
}
int n,h[N];
int x,y,z;
int main() {
	while(~scanf("%d%d%d",&x, &y, &z)) updata(1,x,z-1,1,N,y);
	for(int i=1;i<=N;++i) h[i] = query(1,i,i,1,N);
	for(int i=1;i<=N;++i) if(h[i] != h[i-1]) printf("%d %d ",i,h[i]);
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值