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

  代码如下:

 #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. 关于html5的几个新标签在IE9之前不支持的解决办法

    IE8及之前的浏览器不支持用CSS的方法来使用这些尚未支持的结构元素,为了在Internet Explorer浏览器中也能正常使用这些结构元素,需要使用JavaScript脚本,如下:<scri ...

  2. CentOS下编译安装Apache(httpd)

    官网下载最新版本的apache, apr, apr-util http://httpd.apache.org/download.cgi#apache24 http://apr.apache.org/d ...

  3. 使用ADO对象添加、修改、删除数据

    使用ADO对象对数据库中的数据进行添加.修改和删除等操作.首先创建一个ADO类,通过ADO类连接数据库,并打开记录集.例如,使用ADO对象添加.修改.删除数据,程序设计步骤如下:(1)创建一个基于对话 ...

  4. java邮件收发

    http://blog.csdn.net/ycg01/article/details/1394465 java邮件收发 标签: javaimportexceptionnulluserclass 200 ...

  5. jq的合成事件

    jq中有两个合成事件 hover()和toggle() 1.hover() hover方法用于模拟光标悬停事件.当光标移动到元素上时,会触发指定的第一个函数(enter),当光标移出这个元素时,会触发 ...

  6. STM8|STM32 看门狗使用

    源:STM8|STM32 看门狗使用 STM8和STM32都配备了独立看门狗,其作用之大不言而喻.以下为STM8及STM32的独立看门狗使用例: 对于STM32单片机: #define SYS_IWD ...

  7. (转)Permission denied: win7下面eclipse上传本地文件到DFS && 运行M/R程序时出现的同样的错误解决方法

    原文地址: http://mntms.iteye.com/blog/2095651 hadoopeclipse远程控制权限  情景一: 当在win7下面的eclipse装好插件,首次运行M/R程序的时 ...

  8. CodeForces 158C - Cd and pwd commands(模拟)

    这个题我们又把题意理解错了,队友翻译了以后给我解释,我问这个直接一个单词开头的是要找到这个文件夹吗,他说是,然后我就呵呵了..奔着树形结构去和字符串维护就去了...做了好久都没模拟出来,感觉做出来的人 ...

  9. column name is keyword from

    mysql: select tablename.from from tablename; postgresql: select "from" from tablename; sql ...

  10. 卷积神经网络在tenserflow的实现

    卷积神经网络的理论基础看这篇:http://blog.csdn.net/stdcoutzyx/article/details/41596663/ 卷积神经网络的tenserflow教程看这里:http ...