zoukankan      html  css  js  c++  java
  • HDU 1255 覆盖的面积(线段树:扫描线求面积并)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1255

    题目大意:给你若干个矩形,让你求这些矩形重叠两次及以上的部分的面积。

    解题思路:模板题,跟HDU 1542  Atlantis一样是求面积并,唯一的差别是这题要求的是重叠两次以上的面积,只要将cnt>0的条件改为cnt>1即可。

    代码:

      1 #include<cstdio>
      2 #include<cmath>
      3 #include<cstring>
      4 #include<iostream>
      5 #include<algorithm>
      6 #include<vector>
      7 #include<queue>
      8 #include<set>
      9 #include<map>
     10 #include<stack>
     11 #include<string>
     12 #define LC(a) (a<<1)
     13 #define RC(a) (a<<1|1)
     14 #define MID(a,b) ((a+b)>>1)
     15 using namespace std;
     16 typedef long long LL;
     17 const int INF=0x3f3f3f3f;
     18 const int N=2e3+5;
     19 
     20 struct node{
     21     double x1,x2,h,flag;
     22     node(){}
     23     node(double a,double b,double c,double d){
     24         x1=a;x2=b;h=c;flag=d;
     25     }
     26 }a[N];
     27 
     28 struct Node{
     29     int l,r,cnt;
     30     double sum;
     31 }tree[4*N];
     32 
     33 double X[N];
     34 
     35 bool cmp(node a,node b){
     36     return a.h<b.h;
     37 }
     38 
     39 int bin_search(double num,int l,int r){
     40     while(l<=r){
     41         int mid=(l+r)/2;
     42         if(X[mid]==num)
     43             return mid;
     44         else if(X[mid]<num)
     45             l=mid+1;
     46         else
     47             r=mid-1;
     48     }
     49 }
     50 
     51 void pushup(int p){
     52     tree[p].cnt=(tree[LC(p)].cnt==tree[RC(p)].cnt?tree[LC(p)].cnt:-1);
     53     tree[p].sum=tree[LC(p)].sum+tree[RC(p)].sum;
     54 }
     55 
     56 void pushdown(int p){
     57     tree[LC(p)].cnt=tree[RC(p)].cnt=tree[p].cnt;
     58     //由cnt>0改为cnt>1 
     59     if(tree[p].cnt<=1)
     60         tree[LC(p)].sum=tree[RC(p)].sum=0;
     61     else{
     62         tree[LC(p)].sum=X[tree[LC(p)].r+1]-X[tree[LC(p)].l];
     63         tree[RC(p)].sum=X[tree[RC(p)].r+1]-X[tree[RC(p)].l];
     64     }        
     65 }
     66 
     67 void build(int p,int l,int r){
     68     tree[p].l=l;
     69     tree[p].r=r;
     70     tree[p].cnt=0;
     71     if(l==r){
     72         tree[p].sum=0;
     73         return;
     74     }
     75     build(LC(p),l,MID(l,r));
     76     build(RC(p),MID(l,r)+1,r);
     77     pushup(p);
     78 }
     79 
     80 void update(int p,int l,int r,int cnt){
     81     if(l>tree[p].r||r<tree[p].l)
     82         return;
     83     if(l<=tree[p].l&&r>=tree[p].r&&tree[p].cnt!=-1){
     84         tree[p].cnt+=cnt;
     85         if(tree[p].cnt>=2)
     86             tree[p].sum=X[tree[p].r+1]-X[tree[p].l];
     87         else
     88             tree[p].sum=0;
     89         return;
     90     }
     91     if(tree[p].cnt!=-1)
     92         pushdown(p);
     93     update(LC(p),l,r,cnt);
     94     update(RC(p),l,r,cnt);
     95     pushup(p);
     96 }
     97 
     98 int main(){
     99     int T;
    100     scanf("%d",&T);
    101     while(T--){
    102         int n;
    103         scanf("%d",&n);
    104         int m1=0,m2=1;
    105         for(int i=1;i<=n;i++){
    106             double x1,y1,x2,y2;
    107             scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
    108             X[++m1]=x1;
    109             a[m1]=node(x1,x2,y1,1);
    110             X[++m1]=x2;
    111             a[m1]=node(x1,x2,y2,-1);
    112         }
    113         //横坐标离散化 
    114         sort(a+1,a+1+m1,cmp);
    115         sort(X+1,X+1+m1);
    116         for(int i=2;i<=m1;i++){
    117             if(X[i]!=X[i-1])
    118                 X[++m2]=X[i];
    119         }
    120         build(1,1,m2-1);
    121         double ans=0;
    122         //依次读入扫描线求重叠两次及以上的面积并 
    123         for(int i=1;i<=m1-1;i++){
    124             int l=bin_search(a[i].x1,1,m2);
    125             int r=bin_search(a[i].x2,1,m2)-1;
    126             update(1,l,r,a[i].flag); 
    127             ans+=tree[1].sum*(a[i+1].h-a[i].h);
    128         }
    129         printf("%.2lf
    ",ans);
    130     }
    131     return 0;
    132 }

     

     

  • 相关阅读:
    JPA各种类型映射处理
    HTML URL编码
    C# 温故而知新:Stream篇(二)
    数据集
    C#可调用API接口来获取窗口句柄,代码如下:
    C# 温故而知新:Stream篇(三)
    SQL的主键和外键约束
    C# 温故而知新: 线程篇(三)
    C# 温故而知新:Stream篇(四)
    C# 温故而知新:Stream篇(—)
  • 原文地址:https://www.cnblogs.com/fu3638/p/7619975.html
Copyright © 2011-2022 走看看