zoukankan      html  css  js  c++  java
  • bzoj1645 / P2061 [USACO07OPEN]城市的地平线City Horizon(扫描线)

    P2061 [USACO07OPEN]城市的地平线City Horizon

    扫描线

    扫描线简化版

    流程(本题为例):

    把一个矩形用两条线段(底端点的坐标,向上长度,添加$or$删除)表示,按横坐标排序

    $upd:$本题的底端点坐标简化为$(x,0)$

    蓝后对纵坐标建一棵线段树(本题需要对高度进行离散化)。

    每次对线段树进行覆盖$or$删除区间操作,顺便统计一下$k=$有多少点被覆盖到

    而两次(线段)操作之间的长度为$r=x_{i}-x_{i-1}$

    于是两条线段之间被覆盖的面积即为$k*r$

    (某退役选手又一次省出了宝贵的1.5h)

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 using namespace std;
     6 #define N 40010
     7 struct line{
     8     int l,h,f;// l:横坐标 h:向上高度 f:添加/删除
     9     line(){}
    10     line(int A,int B,int C):
    11         l(A),h(B),f(C){} 
    12     bool operator < (const line &tmp) const{
    13         return l<tmp.l;
    14     }
    15 }a[N<<1]; 
    16 int x[N],n,cnt,tn,sum[N<<2],tag[N<<2],res;
    17 long long ans;
    18 #define lc o<<1
    19 #define rc o<<1|1
    20 #define mid l+((r-l)>>1) 
    21 void upd(int o,int l,int r,line e){
    22     if(l>=r) return; //左端点在本题中简化成0,下同
    23     if(x[r]<=e.h) tag[o]+=e.f;//覆盖层数增加/减少
    24     else{
    25         upd(lc,l,mid,e);
    26         if(e.h>x[mid]) upd(rc,mid,r,e);//注意mid~mid+1的区间不可被忽略
    27     }sum[o]= tag[o]? x[r]-x[l]:sum[lc]+sum[rc];//是否被完全覆盖
    28 }
    29 int main(){
    30     scanf("%d",&n); int q1,q2,q3;
    31     for(int i=1;i<=n;++i){
    32         scanf("%d%d%d",&q1,&q2,&q3);
    33         a[++cnt]=line(q1,q3,1);
    34         a[++cnt]=line(q2,q3,-1);//一个矩形用两条线段表示
    35         x[i+1]=q3;//存横坐标用于离散化
    36     }sort(a+1,a+cnt+1);//(线段)操作按横坐标排序
    37     sort(x+1,x+n+2);x[0]=-1;//注意要加上坐标(0,0)
    38     for(int i=1;i<=n+1;++i)
    39         if(x[i]!=x[i-1]) x[++tn]=x[i];//离散化
    40     upd(1,1,tn,a[1]);
    41     for(int i=2;i<=cnt;++i){
    42         ans+=1ll*sum[1]*(a[i].l-a[i-1].l);//累计两条线段间的面积
    43         upd(1,1,tn,a[i]);
    44     }printf("%lld",ans);
    45     return 0;
    46 }
    View Code
  • 相关阅读:
    linux 学习笔记 groupadd创建组
    linux学习笔记 4建立用户
    Linux学习笔记 3 权限篇
    Linux学习笔记 1 环境变量 2 vi命令
    指针 以及取地址
    练习题
    weblogic domain creation
    hibernate log4j 输出sql
    练习九 组函数应用
    练习八 spool导出
  • 原文地址:https://www.cnblogs.com/kafuuchino/p/10023529.html
Copyright © 2011-2022 走看看