线段树-矩形面积求并

题目链接

题目描述:

给定很多个矩形,给定方式是对角线坐标点.求面积的并。

大致思路:

扫描线+线段树;

  1 #include <stdio.h>
  2 #include <iostream>
  3 #include <algorithm>
  4 #include <string.h>
  5 #include <string>
  6 #include <stdlib.h>
  7 #include <math.h>
  8 #include <time.h>
  9 
 10 using namespace std;
 11 typedef long long int LL;
 12 const int INF=2e9+1e8;
 13 
 14 
 15 
 16 const int maxn=1e6+10;
 17 
 18 
 19 struct Date
 20 {
 21     double l,r,high;
 22     int flag; //false 为 下面的边
 23 } data[maxn];
 24 double myh[maxn],input[maxn];
 25 int n,k;
 26 int getid(double x)
 27 {
 28     return lower_bound(myh+1,myh+k,x)-myh;
 29 }
 30 /**
 31 *
 32 *  线段树
 33 *
 34 */
 35 struct Seg
 36 {
 37     int l,r,val;
 38     double res;
 39 } Tree[maxn];
 40 void build(int i,int l,int r)
 41 {
 42     Tree[i].l=l,Tree[i].r=r;
 43     Tree[i].val=0,Tree[i].res=0;
 44     if(l==r) return ;
 45     int mid=(l+r)>>1;
 46     build(i<<1,l,mid);
 47     build(i<<1|1,mid+1,r);
 48 }
 49 void deal(int i)
 50 {
 51     if(Tree[i].val) Tree[i].res=myh[Tree[i].r+1]-myh[Tree[i].l];
 52     else if(Tree[i].l==Tree[i].r) Tree[i].res=0.;
 53     else Tree[i].res=Tree[i<<1].res+Tree[i<<1|1].res;
 54 }
 55 void update(int i,int l,int r,int x) // 更新区间,并维护投影长度和,
 56 {
 57     if(l>r) return ;
 58     if(Tree[i].l==l&&Tree[i].r==r)
 59     {
 60         Tree[i].val+=x;
 61         deal(i);
 62         return ;
 63     }
 64     int mid=(Tree[i].l+Tree[i].r)>>1;
 65     if(r<=mid) update(i<<1,l,r,x);
 66     else if(l>mid) update(i<<1|1,l,r,x);
 67     else update(i<<1,l,mid,x),update(i<<1|1,mid+1,r,x);
 68     deal(i);
 69 }
 70 
 71 double solve()
 72 {
 73     double ans=0;
 74     update(1,getid(data[0].l),getid(data[0].r)-1,1);
 75 
 76     for(int i=1; i<2*n; i++)
 77     {
 78         ans+=Tree[1].res*(data[i].high-data[i-1].high);
 79         update(1,getid(data[i].l),getid(data[i].r)-1,data[i].flag);
 80     }
 81     return ans;
 82 }
 83 bool cmp(Date a,Date b)
 84 {
 85     return a.high<b.high;
 86 }
 87 int main()
 88 {
 89 //    freopen("in.txt","r",stdin);
 90 //    freopen("out.txt","w",stdout);
 91     while(scanf("%d",&n)!=EOF)
 92     {
 93         if(n==0) return 0;
 94         for(int i=0; i<n; i++)
 95         {
 96             double x1,y1,x2,y2;
 97             scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
 98             data[i].l=x1,data[i].r=x2,data[i].high=y1,data[i].flag=1;
 99             data[n+i].l=x1,data[i+n].r=x2,data[n+i].high=y2,data[i+n].flag=-1;
100             input[i]=x1,input[i+n]=x2;
101         }
102         sort(data,data+2*n,cmp);// 对y进行排序;
103         sort(input,input+2*n);//将x进行排序,离散
104         k=1;
105         myh[k++]=input[0];
106         for(int i=1; i<2*n; i++)
107             if(input[i]!=input[i-1]) myh[k++]=input[i];
108         build(1,1,k-1);
109         printf("%.2lf\n",solve());
110     }
111     return 0;
112 }

 

 
posted @ 2017-05-16 18:26  Code-dream  阅读(383)  评论(0编辑  收藏  举报