博客园 首页 私信博主 显示目录 隐藏目录 管理 动画

扫描线之入门+线段树

扫描线+线段树解决的是矩形覆盖求面积/周长问题

面积版:

也就是给出若干个矩形,最后求总面积(重点是快速解决覆盖问题)

 

 
矩形覆盖

 

三个矩形叠在一起就会产生重复部分,要怎么解决这个问题呢?
此类问题一般都是用线段树辅助扫描法来计算!

扫描线如下图所示,只要求出每一条扫描线的有效长度,就可以得出该区域的实际面积,最后把所有面积相加,即为该多边形的总面积。

 

 
扫描线
大佬地址:https://www.jianshu.com/p/4b71c60e290b
poj 1151
AC:
  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\n",++ant);
139         printf("Total explored area: %.2f\n\n",are);
140     }
141 }
oo

 

posted @ 2019-07-30 08:58  GUET_uzi  阅读(276)  评论(0编辑  收藏  举报

- 创建于 2018年9月1日

这是一位ACM爱好者&数学爱好者的个人站,内容主要是算法&数据结构&数学研究的技术文章,大部分来自学习,部分来源于网络,希望对大家有所帮助。