• 【HDU1542】Atlantis


    题意

       给出n个矩形的左下角和右上角的坐标,计算总的面积(相交部分只算一次)。

    分析

       线段树扫描线的模板题。

       将每个矩形都拆成上下两条线段,然后从下网上扫,当遇到底边时就加上这个区间,遇到顶边时,就减去这个区间。这些都很好理解,但是有一个点我感觉很难受!对于普通线段树,先将区间[1,2]+1,再更新区间[2,3]+1的话,2这个点的值应该是2。但是扫描线来说,2应该是1。因为[1,3]是一条线。我们的解决办法是,在线段树[L,R]的区间内储存[L,R+1]的值

      

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 #include <algorithm>
     5 
     6 using namespace std;
     7 const int maxn=200;
     8 struct Node{
     9     double l,r,h;
    10     int state;
    11     bool operator <(const Node & rhs)const{
    12         return h<rhs.h;
    13     }
    14     Node (){}
    15     Node (double l,double r,double h,int state):l(l),r(r),h(h),state(state){}
    16 }node[maxn];
    17 double v[maxn];
    18 int n,kase;
    19 double x1,y1,x2,y2,ans;
    20 double sumv[4*maxn];
    21 int cover[4*maxn];
    22 
    23 void maintain(int o,int L,int R){
    24     if(cover[o])
    25         sumv[o]=v[R+1]-v[L];
    26     else if(L==R)
    27         sumv[o]=0;
    28     else
    29         sumv[o]=sumv[2*o]+sumv[2*o+1];
    30 }
    31 int ql,qr,vv;
    32 void update(int o,int L,int R){
    33     if(ql<=L&&qr>=R){
    34         cover[o]+=vv;
    35         maintain(o,L,R);
    36         return ;
    37     }
    38     int M=L+(R-L)/2;
    39     if(ql<=M)update(2*o,L,M);
    40     if(qr>M)update(2*o+1,M+1,R);
    41     maintain(o,L,R);
    42 }
    43 int main(){
    44     kase=0;
    45     while(scanf("%d",&n)!=EOF&&n){
    46         int sz=0;
    47         ++kase;
    48         for(int i=1;i<=n;i++){
    49             scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
    50             node[++sz].l=x1,node[sz].r=x2,node[sz].h=y1,node[sz].state=1,v[sz]=x1;
    51             node[++sz].l=x1,node[sz].r=x2,node[sz].h=y2,node[sz].state=-1,v[sz]=x2;
    52         }
    53         sort(node+1,node+1+sz);
    54         sort(v+1,v+1+sz);
    55         int N=unique(v+1,v+1+sz)-v-1;
    56         memset(sumv,0,sizeof(sumv));
    57         memset(cover,0,sizeof(cover));
    58         ans=0;
    59         for(int i=1;i<sz;i++){
    60             ql=lower_bound(v+1,v+1+N,node[i].l)-v,qr=lower_bound(v+1,v+1+N,node[i].r)-v-1,vv=node[i].state;
    61             update(1,1,N);
    62             ans+=sumv[1]*(node[i+1].h-node[i].h);
    63         }
    64         printf("Test case #%d
    ",kase);
    65         printf("Total explored area: %.2f
    ",ans);
    66         printf("
    ");
    67     }
    68 return 0;
    69 }
    View Code
  • 相关阅读:
    (转)HTTP协议
    函数深入理解---函数的定义方式
    DOM模型和事件处理---事件处理
    DOM模型和事件处理---节点操作
    DOM模型和事件处理---基本操作
    常用知识
    窗口对象
    简单的事件处理
    Grunt
    基本操作
  • 原文地址:https://www.cnblogs.com/LQLlulu/p/9038324.html
Copyright © 2020-2023  润新知