覆盖的面积(扫描线求面积交

# 题意

多组测试样例,n表示矩形的个数,每个矩形用左上角和右下角来描述,输出这些矩形的面积交。

# 题解

同面积并思想一样,额外维护一个len2,表示覆盖线段大于2的长度

分为两种情况

1)当前的区间覆盖的线段个数大于2

2)当前区间覆盖次数为1,加上子区间覆盖的1次的线段长度即当前覆盖大于2的总共长度

3)覆盖次数为0,子区间可能存在,累加子区间的覆盖次数大于2的即可

 1 #include <bits/stdc++.h>
 2 #define pb push_back
 3 #define db double
 4 using namespace std;
 5 const int N = 100010;
 6 int n;
 7 struct Segment
 8 {
 9     double x, y1, y2;
10     int k;
11     bool operator< (const Segment &t)const
12     {
13         return x < t.x;
14     }
15 }seg[N * 2];
16 struct Node
17 {
18     int l, r;
19     int cnt;
20     double len;
21     double len2;
22 }tr[N * 8];
23 
24 vector<double> ys;
25 int find(db y){
26     return lower_bound(ys.begin(),ys.end(),y)-ys.begin();
27 }
28 inline void push_up(int u)
29 {
30     if (tr[u].cnt) tr[u].len = ys[tr[u].r + 1] - ys[tr[u].l];//当前区间有覆盖,加上当前区间代表线段的长度
31     else if (tr[u].l != tr[u].r)
32     {
33         tr[u].len = tr[u << 1].len + tr[u << 1 | 1].len;//将当前的总长度传递到根节点
34     }
35     else tr[u].len = 0;
36 
37     if(tr[u].cnt>1) tr[u].len2=ys[tr[u].r + 1] - ys[tr[u].l];//区间多次覆盖
38     else if(tr[u].l==tr[u].r) tr[u].len2=0;
39     else if(tr[u].cnt==1) tr[u].len2=tr[u<<1].len+tr[u<<1|1].len;
40     else tr[u].len2=tr[u<<1].len2+tr[u<<1|1].len2;
41 }
42 inline void build(int u, int l, int r)
43 {
44     tr[u] = {l, r, 0, 0,0};
45     if (l != r)
46     {
47         int mid = l + r >> 1;
48         build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r);
49     }
50 }
51 void change(int u,int l,int r,int k){
52     if(tr[u].l >= l && tr[u].r <= r){
53         tr[u].cnt += k;
54         push_up(u);
55     }
56     else {
57         int mid = tr[u].l + tr[u].r >> 1;
58         if( l <= mid ) change(u<<1,l,r,k);
59         if(r>mid) change(u<<1|1,l,r,k);
60         push_up(u);
61     }
62 }
63 int main(){
64     int t;
65     scanf("%d",&t);
66     while(t--){
67         scanf("%d",&n);
68         ys.clear();
69         for(int i=0,j=0;i<n;i++){
70             double x1,y1,x2,y2;
71             scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
72             ys.pb(y1);
73             ys.pb(y2);
74             seg[j++]={x1,y1,y2,1};
75             seg[j++]={x2,y1,y2,-1};
76         }
77         sort(ys.begin(),ys.end());
78         ys.erase(unique(ys.begin(),ys.end()),ys.end());
79         sort(seg,seg+2*n);
80         build(1,0,ys.size()-2);//线段个数比点的个数少1
81 
82         db res=0;
83         for(int i=0;i<n*2;i++){
84             if(i > 0) res += tr[1].len2*(seg[i].x-seg[i-1].x);
85             change(1,find(seg[i].y1),find(seg[i].y2)-1,seg[i].k);
86         }
87         printf("%.2lf\n", res);
88     }
89 }

 

原文链接: https://www.cnblogs.com/hhyx/p/12514780.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍;

也有高质量的技术群,里面有嵌入式、搜广推等BAT大佬

    覆盖的面积(扫描线求面积交

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/374359

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年3月3日 下午12:08
下一篇 2023年3月3日 下午12:08

相关推荐