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

  代码如下:

 #include <stdio.h>
#include <algorithm>
#include <string.h>
#define t_mid (l+r>>1)
#define ls (o<<1)
#define rs (o<<1|1)
#define lson ls,l,t_mid
#define rson rs,t_mid+1,r
using namespace std;
const int N = + ;
const int MAX = N * ;
const double eps = 1e-; struct seg
{
double x1,x2,y;
int d;
bool operator < (const seg & temp) const
{
return std::fabs(y-temp.y) <= eps ? d > temp.d : y < temp.y;
}
}g[N<<];
int n,tot,ptot;
int lazy[MAX<<];
double pos[MAX],c[MAX<<],cc[MAX<<];
void add(double x1,double x2,double y,int d)
{
tot++;
g[tot] = {x1,x2,y,d};
}
void read()
{
tot = ptot = ;
scanf("%d",&n);
for(int i=;i<=n;i++)
{
double x1,y1,x2,y2;
scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
add(x1,x2,y1,);
add(x1,x2,y2,-);
pos[++ptot] = x1;
pos[++ptot] = x2;
}
sort(g+,g++tot);
sort(pos+,pos++ptot);
int m = ;
for(int i=;i<=ptot;i++)
{
if(std::fabs(pos[i]-pos[i-]) > eps)
{
pos[++m] = pos[i];
}
}
ptot = m;
} int Find(double x)
{
int L = , R = ptot;
while(L <= R)
{
int mid = L + R >> ;
if(std::fabs(pos[mid]-x) <= eps) return mid;
else if(pos[mid] < x) L = mid + ;
else R = mid - ;
}
return -;
} void pushup(int o,int l,int r)
{
if(lazy[o] > ) c[o] = pos[r] - pos[l-];
else if(l == r) c[o] = ;
else c[o] = c[ls] + c[rs];
/*************************/
if(lazy[o] >= ) cc[o] = pos[r] - pos[l-];
else if(l == r) cc[o] = ;
else if(lazy[o] == ) cc[o] = c[ls] + c[rs];
else cc[o] = cc[ls] + cc[rs];
} void update(int o,int l,int r,int ql,int qr,int f)
{
if(ql == l && qr == r)
{
lazy[o] += f;
pushup(o,l,r);
return ;
}
if(qr <= t_mid) update(lson,ql,qr,f);
else if(ql > t_mid) update(rson,ql,qr,f);
else
{
update(lson,ql,t_mid,f);
update(rson,t_mid+,qr,f);
}
pushup(o,l,r);
} void solve()
{
memset(lazy,,sizeof(lazy));
memset(c,,sizeof(c));
memset(cc,,sizeof(cc));
double ans = ;
for(int i=;i<=tot;)
{
int j = i;
while(j <= tot && std::fabs(g[i].y-g[j].y) <= eps)
{
int L = Find(g[j].x1);
int R = Find(g[j].x2);
/*
下面的L要加1是因为两个点重合但是其实线段是不重合的,
所以线段树内不能让他们管辖同一块地方
而pushup里面再L减1是因为,计算两点之间的距离要用原来的点算
*/
update(,,MAX,L+, R, g[j].d);
j++;
}
if(j <= tot) ans += 1.0*(g[j].y-g[i].y) * cc[];
i = j;
}
printf("%.2f\n",ans);
} int main()
{
int T;
scanf("%d",&T);
while(T--)
{
read();
solve();
}
return ;
}

HDU 1255 覆盖的面积 ——(线段树+扫描线)的更多相关文章

  1. HDU 1255 覆盖的面积 (线段树+扫描线+离散化)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1255 题意很清楚,就是让你求矩阵之间叠加层数大于1的矩形块的面积和. 因为n只有1000,所以我离散化 ...

  2. HDU 1255 覆盖的面积 线段树+扫描线

    同 POJ1151 这次是两次 #include <iostream> #include <algorithm> #include <cstdio> #includ ...

  3. hdu 1255 覆盖的面积 (线段树处理面积覆盖问题(模板))

    http://acm.hdu.edu.cn/showproblem.php?pid=1255 覆盖的面积 Time Limit: 10000/5000 MS (Java/Others)    Memo ...

  4. HDU 1255 覆盖的面积(线段树面积并)

      描述 给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积. Input 输入数据的第一行是一个正整数T(1<=T<=100),代表测试数据的数量.每个测试数据的第一行是一个正 ...

  5. HDU 1255 覆盖的面积(线段树:扫描线求面积并)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1255 题目大意:给你若干个矩形,让你求这些矩形重叠两次及以上的部分的面积. 解题思路:模板题,跟HDU ...

  6. hdu1255 覆盖的面积 线段树-扫描线

    矩形面积并 线段树-扫描线裸题 #include<stdio.h> #include<string.h> #include<algorithm> #include& ...

  7. HDU - 1255 覆盖的面积(线段树求矩形面积交 扫描线+离散化)

    链接:线段树求矩形面积并 扫描线+离散化 1.给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积. 2.看完线段树求矩形面积并 的方法后,再看这题,求的是矩形面积交,类同. 求面积时,用被覆 ...

  8. hdu 1255 覆盖的面积(线段树 面积 交) (待整理)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1255 Description 给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积.   In ...

  9. hdu 1255 覆盖的面积(求覆盖至少两次以上的面积)

    了校赛,还有什么途径可以申请加入ACM校队?  覆盖的面积 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K ...

  10. HDU 1264 Counting Squares (线段树-扫描线-矩形面积并)

    版权声明:欢迎关注我的博客.本文为博主[炒饭君]原创文章,未经博主同意不得转载 https://blog.csdn.net/a1061747415/article/details/25471349 P ...

随机推荐

  1. js框架——angular.js(4)

    1. angular中的对象 其实也不用多说的,前台是可以提取后台定义的对象的—— <body ng-app="MyApp"> <div ng-controlle ...

  2. List<Map>去重排序

    数据格式 [ { "id":"d3e8a9d6-e4c6-4dd8-a94f-07733d3c1b59", "parentId":" ...

  3. JavaScript基础教程

    功能介绍: (1)数据验证 弹出提示的对话框,产生判断的效果. (2)气泡提示窗口 右下角等等一类的窗口 (3)产生新窗口 (4)无边框窗口背景变灰,也是可以节约系统资源的

  4. java工程开发之图形化界面之(第三课)

    上面我们讲述了通过JOptionPane进行文本I/O操作,一个是通过JOptionPane来获取的 参考链接:http://blog.sina.com.cn/s/blog_993d254201013 ...

  5. JSON对象长度和遍历方法(转)

    最 近在修改一个HTML页面的JS的时候遍历JSON对象,却怎么也调试不通过.怪这个HTML网页不知道用了什么方法禁止了js错误提示,刚开始的时候不 知道有这个问题,用chrome的开发人员工具都没发 ...

  6. 使用float和display:block将内联元素转换成块元素的不同点

    使用float和display:block将内联元素转换成块元素的不同点 使用float和display:block将内联元素转换成块元素的不同点:内联元素可以转换成块级元素,常用的方法比如可以为内联 ...

  7. tps,qps

    http://blog.itpub.net/22664653/viewspace-767265/

  8. sql语句删除由于无主键导致完全重复的数据方法

    sql语句删除由于无主键导致完全重复的数据方法 select distinct * into #Tmp from t_column drop table t_column select * into ...

  9. constraint 摘自群主大大

    CONSTRAINT 子句 限制和索引相似,虽然限制也能被用于建立和另一个表的关联. 用 ALTER TABLE 和 CREATE TABLE 语句中的 CONSTRAINT 子句来建立或删除条件.C ...

  10. Python3基础 list(reversed()) 将一个列表逆转并输出

    镇场诗: 诚听如来语,顿舍世间名与利.愿做地藏徒,广演是经阎浮提. 愿尽吾所学,成就一良心博客.愿诸后来人,重现智慧清净体.-------------------------------------- ...