zoukankan      html  css  js  c++  java
  • HDU 1255 覆盖的面积 ——(线段树+扫描线)

      又做了一题扫描线以后对节点的覆盖标记理解的更加深刻了。

      代码如下:

      1 #include <stdio.h>
      2 #include <algorithm>
      3 #include <string.h>
      4 #define t_mid (l+r>>1)
      5 #define ls (o<<1)
      6 #define rs (o<<1|1)
      7 #define lson ls,l,t_mid
      8 #define rson rs,t_mid+1,r
      9 using namespace std;
     10 const int N = 1000 + 5;
     11 const int MAX = N * 2;
     12 const double eps = 1e-6;
     13 
     14 struct seg
     15 {
     16     double x1,x2,y;
     17     int d;
     18     bool operator < (const seg & temp) const
     19     {
     20         return std::fabs(y-temp.y) <= eps ? d > temp.d : y < temp.y;
     21     }
     22 }g[N<<1];
     23 int n,tot,ptot;
     24 int lazy[MAX<<2];
     25 double pos[MAX],c[MAX<<2],cc[MAX<<2];
     26 void add(double x1,double x2,double y,int d)
     27 {
     28     tot++;
     29     g[tot] = {x1,x2,y,d};
     30 }
     31 void read()
     32 {
     33     tot = ptot = 0;
     34     scanf("%d",&n);
     35     for(int i=1;i<=n;i++)
     36     {
     37         double x1,y1,x2,y2;
     38         scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
     39         add(x1,x2,y1,1);
     40         add(x1,x2,y2,-1);
     41         pos[++ptot] = x1;
     42         pos[++ptot] = x2;
     43     }
     44     sort(g+1,g+1+tot);
     45     sort(pos+1,pos+1+ptot);
     46     int m = 1;
     47     for(int i=2;i<=ptot;i++)
     48     {
     49         if(std::fabs(pos[i]-pos[i-1]) > eps)
     50         {
     51             pos[++m] = pos[i];
     52         }
     53     }
     54     ptot = m;
     55 }
     56 
     57 int Find(double x)
     58 {
     59     int L = 1, R = ptot;
     60     while(L <= R)
     61     {
     62         int mid = L + R >> 1;
     63         if(std::fabs(pos[mid]-x) <= eps) return mid;
     64         else if(pos[mid] < x) L = mid + 1;
     65         else R = mid - 1;
     66     }
     67     return -1;
     68 }
     69 
     70 void pushup(int o,int l,int r)
     71 {
     72     if(lazy[o] > 0) c[o] = pos[r] - pos[l-1];
     73     else if(l == r) c[o] = 0;
     74     else c[o] = c[ls] + c[rs];
     75     /*************************/
     76     if(lazy[o] >= 2) cc[o] = pos[r] - pos[l-1];
     77     else if(l == r) cc[o] = 0;
     78     else if(lazy[o] == 1) cc[o] = c[ls] + c[rs];
     79     else cc[o] = cc[ls] + cc[rs];
     80 }
     81 
     82 void update(int o,int l,int r,int ql,int qr,int f)
     83 {
     84     if(ql == l && qr == r)
     85     {
     86         lazy[o] += f;
     87         pushup(o,l,r);
     88         return ;
     89     }
     90     if(qr <= t_mid) update(lson,ql,qr,f);
     91     else if(ql > t_mid) update(rson,ql,qr,f);
     92     else
     93     {
     94         update(lson,ql,t_mid,f);
     95         update(rson,t_mid+1,qr,f);
     96     }
     97     pushup(o,l,r);
     98 }
     99 
    100 void solve()
    101 {
    102     memset(lazy,0,sizeof(lazy));
    103     memset(c,0,sizeof(c));
    104     memset(cc,0,sizeof(cc));
    105     double ans = 0;
    106     for(int i=1;i<=tot;)
    107     {
    108         int j = i;
    109         while(j <= tot && std::fabs(g[i].y-g[j].y) <= eps)
    110         {
    111             int L = Find(g[j].x1);
    112             int R = Find(g[j].x2);
    113             /*
    114             下面的L要加1是因为两个点重合但是其实线段是不重合的,
    115             所以线段树内不能让他们管辖同一块地方
    116             而pushup里面再L减1是因为,计算两点之间的距离要用原来的点算
    117             */
    118             update(1,0,MAX,L+1, R, g[j].d);
    119             j++;
    120         }
    121         if(j <= tot) ans += 1.0*(g[j].y-g[i].y) * cc[1];
    122         i = j;
    123     }
    124     printf("%.2f
    ",ans);
    125 }
    126 
    127 int main()
    128 {
    129     int T;
    130     scanf("%d",&T);
    131     while(T--)
    132     {
    133         read();
    134         solve();
    135     }
    136     return 0;
    137 }
  • 相关阅读:
    安装docker (centos7.6)
    idea docker docker-compose发布springboot站点到tomcat
    tomcat启动慢的解决办法
    skywalking6.3.0安装(centos7.6)
    RocketMQ集群安装 2主2从 console
    RocketMQ官方启动脚本不支持jdk11的修改
    python在windows上创建虚拟环境
    JVM之Java运行时数据区(线程共享区)
    Dijkstra算法和Floyd算法
    JVM之Java运行时数据区(线程隔离区)
  • 原文地址:https://www.cnblogs.com/zzyDS/p/6287583.html
Copyright © 2011-2022 走看看