扫描线+线段树解决的是矩形覆盖求面积/周长问题
面积版:
也就是给出若干个矩形,最后求总面积(重点是快速解决覆盖问题)
![](http://upload-images.jianshu.io/upload_images/4378213-a8369c7f4840d44a.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1000/format/webp)
矩形覆盖
三个矩形叠在一起就会产生重复部分,要怎么解决这个问题呢?
此类问题一般都是用线段树辅助扫描法来计算!
扫描线如下图所示,只要求出每一条扫描线的有效长度,就可以得出该区域的实际面积,最后把所有面积相加,即为该多边形的总面积。
![](http://upload-images.jianshu.io/upload_images/4378213-bffbf68e012ec1ee.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1000/format/webp)
扫描线
大佬地址:https://www.jianshu.com/p/4b71c60e290b
poj 1151
AC:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream> 2 #include<cstring> 3 //#include<bits/stdc++.h> 4 #include<math.h> 5 #include<algorithm> 6 #include<queue> 7 #include<stack> 8 #include<cstdio> 9 #include<map> 10 #include<set> 11 #define si(a) scanf("%d",&a) 12 #define sl(a) scanf("%lld",&a) 13 #define sii(a,b) scanf("%d%d",&a,&b) 14 #define sll(a,b) scanf("%lld%lld",&a,&b) 15 #define queues priority_queue 16 #define mod 1000000007 17 #define mem(a) memset(a,0,sizeof(a)); 18 #define def(a) ((a)&(-a)) 19 #define fi first 20 #define se second 21 #define mp make_pair 22 #define pb push_back 23 #define mem(a,b) memset(a,b,sizeof(a)); 24 typedef long long ll; 25 //priority_queue<ll,vector<ll >,greater<ll > >q; 26 const int INF=0x3f3f3f3f; 27 //const double E=exp(1); 28 //const double PI=acos(-1); 29 using namespace std; 30 //__builtin_popcount 31 //priority_queue 32 const ll MAX=100000; 33 //ll gcd(ll a,ll b){return b==0?a:gcd(b,a%b);} 34 //ll kc(ll a,ll b){ll c=1;while(b){if(b&1)c=(c*a)%mod;a=(a*a)%mod;b>>=1;}return c;} 35 //bool cmp(double x,double y){return x>y;} 36 //ll F[50003*3]; 37 //ll Find(ll a){return F[a]<0?a:F[a]=Find(F[a]);} 38 //ll same(ll a,ll b){if(Find(a)==Find(b))return 1;return 0;} 39 //ll up1(ll a,ll b){ll x,y;x=Find(a);y=Find(b);if(x!=y)F[x]=y;return 0;} 40 //int read(){int x=0,f=1;char s=getchar();for(; s>'9'||s<'0'; s=getchar()) if(s=='-') f=-1;for(; s>='0'&&s<='9'; s=getchar()) x=x*10+s-'0';return x*f;} 41 struct Node 42 { 43 double xl,xr,y; 44 int s; 45 Node(double x,double x1,double y1,int s1):xl(x),xr(x1),y(y1),s(s1) {} 46 bool operator <(Node z) 47 { 48 return y<z.y; 49 } 50 Node() {} 51 } node[203]; 52 struct Tree 53 { 54 int tl,tr; 55 int s; 56 double len; 57 } tree[203<<2]; 58 double X[203],X1[203]; 59 int m; 60 void build(int id,int l,int r)//初始化 61 { 62 tree[id].tl=l; 63 tree[id].tr=r; 64 tree[id].s=0; 65 tree[id].len=0; 66 if(l==r)return ; 67 int mid=(l+r)>>1; 68 build(id<<1,l,mid); 69 build(id<<1|1,mid+1,r); 70 } 71 int b=0; 72 int c; 73 void pushup(int id)//更新 74 { 75 if(tree[id].s) 76 { 77 tree[id].len=X[tree[id].tr+1]-X[tree[id].tl]; 78 } 79 else if(tree[id].tr==tree[id].tl) tree[id].len=0; 80 else 81 { 82 tree[id].len=tree[id<<1].len+tree[id<<1|1].len; 83 } 84 } 85 86 void update(int id,int l,int r,int v) 87 { 88 int tl; 89 int tr; 90 tl=tree[id].tl; 91 tr=tree[id].tr; 92 if(l<=tl&&tr<=r) 93 { 94 tree[id].s+=v; 95 pushup(id); 96 return ; 97 } 98 int mid=(tr+tl)>>1; 99 if(mid>=l) update(id<<1,l,r,v); 100 if(mid<r)update(id<<1|1,l,r,v); 101 pushup(id); 102 103 } 104 int main() 105 { 106 // ios::sync_with_stdio(false); 107 int t; 108 int ant=0; 109 while(scanf("%d",&t)&&t) 110 { 111 m=0; 112 for(int i=1; i<=t; i++) 113 { 114 double x1,x2,y1,y2; 115 scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2); 116 node[++m]=Node(x1,x2,y1,1); 117 X1[m]=x1; 118 node[++m]=Node(x1,x2,y2,-1); 119 X1[m]=x2; 120 } 121 sort(X1+1,X1+m+1); 122 sort(node+1,node+1+m); 123 double are=0; 124 int mm=0; 125 X[++mm]=X1[1]; 126 for(int i=2; i<=m; i++) //去重 127 if(X1[i]!=X1[i-1]) 128 X[++mm]=X1[i]; 129 build(1,1,mm); 130 for(int i=1; i<=m; i++) 131 { 132 int l=lower_bound(X+1,X+1+mm,node[i].xl)-X; 133 int r=lower_bound(X+1,X+1+mm,node[i].xr)-X-1; 134 c=i; 135 update(1,l,r,node[i].s); 136 are+=tree[1].len*(node[i+1].y-node[i].y); 137 } 138 printf("Test case #%d ",++ant); 139 printf("Total explored area: %.2f ",are); 140 } 141 }