矩形面积并

线段树-扫描线裸题

 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<algorithm>
 4 #include<math.h>
 5 using namespace std;
 6 const int maxm=2e3+5;
 7 const double eps=1e-5;
 8 
 9 struct seg{
10     double x,y1,y2;
11     int c;
12     bool operator < (const seg a)const{
13         return x<a.x;
14     }
15 }s[maxm];
16 
17 double y[maxm];
18 double st[maxm<<2],st2[maxm<<2];
19 int cov[maxm<<2];
20 
21 void pushup(int o,int l,int r){
22     if(cov[o]>1){
23         st[o]=st2[o]=y[r]-y[l];
24     }
25     else if(cov[o]==1){
26         st[o]=y[r]-y[l];
27         if(l+1==r)st2[o]=0;
28         else st2[o]=st[o<<1]+st[o<<1|1];
29     }
30     else{
31         if(l+1==r)st[o]=st2[o]=0;
32         else{
33             st[o]=st[o<<1]+st[o<<1|1];
34             st2[o]=st2[o<<1]+st2[o<<1|1];
35         }
36     }
37 }
38 
39 void update(int o,int l,int r,seg a){
40     if(y[l]>=a.y1&&y[r]<=a.y2){
41         cov[o]+=a.c;
42         pushup(o,l,r);
43         return;
44     }
45     if(l+1==r)return;
46     int m=l+((r-l)>>1);
47     if(a.y1<=y[m])update(o<<1,l,m,a);
48     if(a.y2>y[m])update(o<<1|1,m,r,a);
49     pushup(o,l,r);
50 }
51 
52 int main(){
53     int T;
54     scanf("%d",&T);
55     while(T--){
56         int n;
57         scanf("%d",&n);
58         memset(st,0,sizeof(st));
59         memset(cov,0,sizeof(cov));
60         memset(st2,0,sizeof(st2));
61         for(int i=1;i<=n;++i){
62             double x1,y1,x2,y2;
63             scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
64         /*    s[2*i-1].x=x1;
65             s[2*i].x=x2;
66             s[2*i-1].y1=y1;
67             s[2*i].y1=y1;
68             s[2*i-1].y2=y2;
69             s[2*i].y2=y2;
70             s[2*i-1].c=1;
71             s[2*i].c=-1;
72             y[2*i-1]=y1;
73             y[2*i]=y2;*/
74             s[2*i-1].x=x1;s[2*i-1].y1=y1;s[2*i-1].y2=y2;s[2*i-1].c=1;
75             y[2*i-1]=y1;
76             s[2*i].x=x2;s[2*i].y1=y1;s[2*i].y2=y2;s[2*i].c=-1;
77             y[2*i]=y2;
78         }
79         sort(y+1,y+2*n+1);
80         sort(s+1,s+2*n+1);
81 /*        int cnt=1;
82         for(int i=2;i<=2*n;++i){
83             if(y[i]!=y[i-1])y[++cnt]=y[i];
84         }*/
85         int cnt=2*n;
86         double ans=0;
87         update(1,1,cnt,s[1]);
88         for(int i=2;i<=2*n;++i){
89             ans+=st2[1]*(s[i].x-s[i-1].x);
90             update(1,1,cnt,s[i]);
91         }
92         printf("%.2lf\n",ans);
93     }
94     return 0;
95 }
View Code