• 【BZOJ1645】[Usaco2007 Open]City Horizon 城市地平线 离散化+线段树


    【BZOJ1645】[Usaco2007 Open]City Horizon 城市地平线

    Description

    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 A_i through B_i along the horizon (1 <= A_i < B_i <= 1,000,000,000) and has height H_i (1 <= H_i <= 1,000,000,000). Determine the area, in square units, of the aggregate silhouette formed by all N buildings.

    N个矩形块,交求面积并.

    Input

    * Line 1: A single integer: N

    * Lines 2..N+1: Input line i+1 describes building i with three space-separated integers: A_i, B_i, and H_i

    Output

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

    Sample Input

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

    Sample Output

    16

    OUTPUT DETAILS:

    The first building overlaps with the fourth building for an area of 1
    square unit, so the total area is just 3*1 + 1*4 + 2*2 + 2*3 - 1 = 16.

    题解:一看就是离散化+线段树的题,可以先将h离散,再按a,b排序,用线段树维护扫描线来做,不过这样比较麻烦。

    因为本题中所有的矩形底边都在同一直线上,所以我们可以把这些矩形整体看成一棵线段树,线段树的区间就是每个a,b,线段树的权值就是h,然后按h排序,从小到大一个一个加到线段树里就行了。

    注意:a和b离散化后是2*40000的空间,所以线段树要开8*40000!2*4==8!!!

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #define lson x<<1
    #define rson x<<1|1
    using namespace std;
    const int maxn=40010;
    typedef long long ll;
    struct edges
    {
        ll pos,org;
    }s[maxn<<1];
    struct house
    {
        ll sa,sb,sh;
    }p[maxn];
    int n,m;
    ll ts[maxn<<3],tag[maxn<<3],ref[maxn<<1];
    bool cmp1(edges a,edges b)
    {
        return a.pos<b.pos;
    }
    bool cmp2(house a,house b)
    {
        return a.sh<b.sh;
    }
    void pushdown(int l,int r,int x)
    {
        if(tag[x])
        {
            int mid=l+r>>1;
            ts[lson]=(ref[mid]-ref[l])*tag[x],ts[rson]=(ref[r]-ref[mid])*tag[x];
            tag[lson]=tag[rson]=tag[x];
            tag[x]=0;
        }
    }
    void pushup(int x)
    {
        ts[x]=ts[lson]+ts[rson];
    }
    void updata(int l,int r,int x,int a,int b,ll v)
    {
        if(a<=l&&r<=b)
        {
            ts[x]=(ref[r]-ref[l])*v;
            tag[x]=v;
            return ;
        }
        pushdown(l,r,x);
        int mid=l+r>>1;
        if(b<=mid)    updata(l,mid,lson,a,b,v);
        else if(a>=mid)    updata(mid,r,rson,a,b,v);
        else    updata(l,mid,lson,a,b,v),updata(mid,r,rson,a,b,v);
        pushup(x);
    }
    int main()
    {
        scanf("%d",&n);
        int i;
        for(i=1;i<=n;i++)
        {
            scanf("%lld%lld%lld",&p[i].sa,&p[i].sb,&p[i].sh);
            s[i*2-1].pos=p[i].sa,s[i*2].pos=p[i].sb;
            s[i*2-1].org=s[i*2].org=i;
        }
        sort(s+1,s+2*n+1,cmp1);
        for(i=1;i<=2*n;i++)
        {
            if(s[i].pos>ref[m])    ref[++m]=s[i].pos;
            if(s[i].pos==p[s[i].org].sa)    p[s[i].org].sa=m;
            else    p[s[i].org].sb=m;
        }
        sort(p+1,p+n+1,cmp2);
        for(i=1;i<=n;i++)
            updata(1,m,1,p[i].sa,p[i].sb,p[i].sh);
        printf("%lld",ts[1]);
        return 0;
    }
  • 相关阅读:
    C++ string 类的 find 方法实例详解
    linux系统中errno与error对照表
    tshark (wireshark)笔记
    自己签发免费ssl证书
    Go语言练习:网络编程实例——简易图片上传网站
    java开源工具包-Jodd框架
    数据库性能瓶颈解决方案
    [转载]如何快速学习一门技术
    [转载]IBM公司发布了最新的power7服务器p750 p770 p780
    计算机组成原理 — 指令系统
  • 原文地址:https://www.cnblogs.com/CQzhangyu/p/6281746.html
Copyright © 2020-2023  润新知