题目传送门
天际线
题目大意
在二维坐标系的第一象限中,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;
}