• [POJ3277]City Horizon


    [POJ3277]City Horizon

    试题描述

    Farmer John has taken his cows on a trip to the city! As the sun sets, the cows gaze at the city horizon and observe the beautiful silhouettes formed by the rectangular buildings.

    The entire horizon is represented by a number line with N (1 ≤ N ≤ 40,000) buildings. Building i's silhouette has a base that spans locations Ai through Bi along the horizon (1 ≤ Ai < Bi ≤ 1,000,000,000) and has height Hi (1 ≤ Hi ≤ 1,000,000,000). Determine the area, in square units, of the aggregate silhouette formed by all N buildings.

    输入

    Line 1: A single integer: N Lines 2..N+1: Input line i+1 describes building i with three space-separated integers: Ai, Bi, and Hi

    输出

    Line 1: The total area, in square units, of the silhouettes formed by all N buildings

    输入示例

    4
    2 5 1
    9 10 4
    6 8 2
    4 6 3

    输出示例

    16

    数据规模及约定
    见“试题描述

    题解

    上一题的代码改一改就好了。

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cctype>
    #include <algorithm>
    using namespace std;
    
    int read() {
    	int x = 0, f = 1; char c = getchar();
    	while(!isdigit(c)){ if(c == '-') f = -1; c = getchar(); }
    	while(isdigit(c)){ x = x * 10 + c - '0'; c = getchar(); }
    	return x * f;
    }
    
    #define maxn 40010
    #define LL long long
    int n, cnt, ca, cd;
    struct Rec {
    	LL x1, y1, x2, y2;
    	Rec() {}
    	Rec(LL _1, LL _2, LL _3, LL _4): x1(_1), y1(_2), x2(_3), y2(_4) {}
    } rs[maxn];
    struct Rec_int { int x1, y1, x2, y2; } rsi[maxn];
    LL num[maxn<<1], A[maxn<<1], B[maxn<<1];
    struct Line {
    	int l, r, x;
    	Line() {}
    	Line(int _1, int _2, int _3): l(_1), r(_2), x(_3) {}
    	bool operator < (const Line& t) const { return x < t.x; }
    } ad[maxn], de[maxn];
    
    LL sumv[maxn<<3];
    int addv[maxn<<3];
    void build(int L, int R, int o) {
    	if(L == R) {
    		sumv[o] = 0;
    		addv[o] = 0;
    		return ;
    	}
    	int M = L + R >> 1, lc = o << 1, rc = lc | 1;
    	build(L, M, lc); build(M+1, R, rc);
    	sumv[o] = 0; addv[o] = 0;
    	return ;
    }
    void update(int L, int R, int o, int ql, int qr, int v) {
    	int M = L + R >> 1, lc = o << 1, rc = lc | 1;
    	if(ql <= L && R <= qr) {
    		addv[o] += v;
    		if(addv[o]) sumv[o] = A[R] - A[L-1];
    		else if(L == R) sumv[o] = 0;
    		else sumv[o] = sumv[lc] + sumv[rc];
    		return ;
    	}
    	if(ql <= M) update(L, M, lc, ql, qr, v);
    	if(qr > M) update(M+1, R, rc, ql, qr, v);
    	sumv[o] = addv[o] ? A[R] - A[L-1] : sumv[lc] + sumv[rc];
    	return ;
    }
    
    int main() {
    	int kase = 0;
    	n = read();
    	cnt = 0;
    	for(int i = 1; i <= n; i++) {
    		int l = read(), r = read(), h = read();
    		rs[i] = Rec(l, 0, r, h);
    		num[++cnt] = l; num[++cnt] = r;
    	}
    	sort(num + 1, num + cnt + 1);
    	cnt = unique(num + 1, num + cnt + 1) - num - 1;
    	int tcnt = cnt;
    	for(int i = 1; i < cnt; i++) A[i] = num[i+1] - num[1];
    	for(int i = 1; i <= n; i++) {
    		rsi[i].x1 = lower_bound(num + 1, num + cnt + 1, rs[i].x1) - num;
    		rsi[i].x2 = lower_bound(num + 1, num + cnt + 1, rs[i].x2) - num - 1;
    	}
    	cnt = 0;
    	for(int i = 1; i <= n; i++)
    		num[++cnt] = rs[i].y1, num[++cnt] = rs[i].y2;
    	sort(num + 1, num + cnt + 1);
    	cnt = unique(num + 1, num + cnt + 1) - num - 1;
    	for(int i = 1; i < cnt; i++) B[i] = num[i+1] - num[i];
    	ca = cd = 0;
    	for(int i = 1; i <= n; i++) {
    		rsi[i].y1 = lower_bound(num + 1, num + cnt + 1, rs[i].y1) - num;
    		rsi[i].y2 = lower_bound(num + 1, num + cnt + 1, rs[i].y2) - num;
    		ad[++ca] = Line(rsi[i].x1, rsi[i].x2, rsi[i].y1);
    		de[++cd] = Line(rsi[i].x1, rsi[i].x2, rsi[i].y2);
    	}
    	
    	sort(ad + 1, ad + ca + 1);
    	sort(de + 1, de + cd + 1);
    	LL ans = 0;
    	int ka = 1, kd = 1;
    	build(1, tcnt, 1);
    	for(int i = 1; i <= cnt; i++) {
    		while(ka <= ca && ad[ka].x == i)
    			update(1, tcnt, 1, ad[ka].l, ad[ka].r, 1), ka++;
    		while(kd <= cd && de[kd].x == i)
    			update(1, tcnt, 1, de[kd].l, de[kd].r, -1), kd++;
    		if(i < cnt) ans += sumv[1] * B[i];
    	}
    	printf("%lld
    ", ans);
    	
    	return 0;
    }
    
  • 相关阅读:
    利用Windows消息循环,使窗体不能改变大小
    重磅发布全总结丨一文看懂阿里云弹性计算年度峰会
    阿里云弹性计算首席架构师分享云上应用架构演进三大方向
    只需5步!在轻量应用服务器部署Hexo博客
    阿里云手机正式公测,定义手机全新接入方式
    云服务器ECS年终特惠,老用户新购优惠低至4折
    阿里云发布CloudOps白皮书,ECS自动化运维套件新升级
    快速部署阿里云WebIDE(DevStudio)并参与开源项目开发
    抢先看! 2021阿里云弹性计算年度峰会嘉宾演讲内容提前曝光
    饿了么资深架构师分享云上基础架构演进
  • 原文地址:https://www.cnblogs.com/xiao-ju-ruo-xjr/p/5960700.html
Copyright © 2020-2023  润新知