• 扫描线之入门+线段树


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

    面积版:

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

     
    矩形覆盖

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

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

     
    扫描线
    大佬地址: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
    ",++ant);
    139         printf("Total explored area: %.2f
    
    ",are);
    140     }
    141 }
    oo
  • 相关阅读:
    ubuntu18.04更新源
    机器学习网址
    ubuntu18.04下安装Anaconda及numpy、matplotlib
    google云使用记录
    tensorflow省钱方案-ml-engine
    Angular 创建项目
    Angular 环境搭建
    android APP国际化一键切换实现
    android 上下滑动标题栏和状态栏改变颜色实现
    android滑动标题栏渐变实现
  • 原文地址:https://www.cnblogs.com/zxz666/p/11267879.html
Copyright © 2020-2023  润新知