zoukankan      html  css  js  c++  java
  • BZOJ_1654_[Usaco2007 Open]City Horizon 城市地平线_扫描线

    BZOJ_1654_[Usaco2007 Open]City Horizon 城市地平线_扫描线

    Description

    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


    裸的扫描线,这里从左往右扫。

    先将x轴向上平移一个单位,避免处理麻烦的区间长度问题。

    然后每个矩形拆成两条竖线,从左往右扫。

    需要在线段树上维护一些点是否存在。

    每个节点记录sum和raw,当sum>0时raw=r-l+1,否则等于两个儿子的raw之和,每次修改都要pushup一下。

    代码:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    #define N 80050
    #define maxn 1000000000
    struct Line {
        int y_1,y_2,x,flg;
        Line() {}
        Line(int y__1,int y__2,int x_,int flg_) :
            y_1(y__1),y_2(y__2),x(x_),flg(flg_) {}
        bool operator < (const Line &u) const {
            return x<u.x;
        }
    }a[N];
    int t[N*40],ls[N*40],rs[N*40],cnt,n,raw[N*40],add[N*40];
    void pushup(int l,int r,int p) {
        if(t[p]>0) raw[p]=r-l+1;
        else if(l==r) raw[p]=0;
        else raw[p]=raw[ls[p]]+raw[rs[p]]; 
    }
    void update(int l,int r,int x,int y,int v,int &p) {
        if(!p) p=++cnt;
        if(x<=l&&y>=r) {
            t[p]+=v; pushup(l,r,p);
            return ;
        }
        int mid=(l+r)>>1;
        if(x<=mid) update(l,mid,x,y,v,ls[p]);
        if(y>mid) update(mid+1,r,x,y,v,rs[p]);
        pushup(l,r,p);
    }
    int main() {
        scanf("%d",&n);
        int i,x_1,x_2,h,tot=0;
        for(i=1;i<=n;i++) {
            scanf("%d%d%d",&x_1,&x_2,&h);
            a[++tot]=Line(1,h,x_1,1);
            a[++tot]=Line(1,h,x_2,-1);
        }
        sort(a+1,a+tot+1);
        int root=0;
        update(1,maxn,a[1].y_1,a[1].y_2,a[1].flg,root);
        long long ans=0;
        for(i=2;i<=tot;i++) {
            ans+=1ll*(a[i].x-a[i-1].x)*raw[1];
            update(1,maxn,a[i].y_1,a[i].y_2,a[i].flg,root);
        }
        printf("%lld
    ",ans);
    }
    
  • 相关阅读:
    jQuery使用工具集
    JQuery解决鼠标单双击冲突问题
    线程池
    配置文件application.properties参数详解
    SpringBoot整合SpringDataJPA
    获取数据库的自增主键(六)
    【使用篇二】邮箱自动化配置集成(18)
    Quartz自动化配置集成
    Cron表达式详解
    标准盒模型和怪异盒模型的区别
  • 原文地址:https://www.cnblogs.com/suika/p/9063254.html
Copyright © 2011-2022 走看看