http://acm.hdu.edu.cn/showproblem.php?pid=1255

典型线段树辅助扫描线,顾名思义扫描线就是相当于yy出一条直线从左到右(也可以从上到下)扫描过去,此时先将所有的横坐标和纵坐标排序

因为是从左到右扫描,那么横坐标应该离散化一下

当扫描线依次扫描的时候,依次扫描到的纵区间在线段树中查找,依据是上边还是下边记录,上边就是-1,下边就是+1,

如果某区间记录值为0的时候,代表没有被覆盖,为1的时候代表覆盖一次,为2代表覆盖两次(不会出现为负数的情况)

最后将依次扫描的覆盖两次的纵区间长度乘以以此的横坐标的和就行

所以http://acm.hdu.edu.cn/search.php?action=listproblem hdu1542 就在稍微改改这题的代码就行了

code

 #include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
struct node{
double x,y1,y2;
double flag;
};
node num[];
double a[];
bool cmp(node q,node w){return q.x<w.x;}
struct point {
int l,r,mark;
double lf,rf;
double once; //覆盖一次
double twice;//覆盖两次
};
point tree[*];
void build(int i,int left,int right)
{
tree[i].l=left,tree[i].r=right;
tree[i].once=tree[i].twice=;
tree[i].lf=a[left];
tree[i].rf=a[right];
if (left+==right) return ;
int mid=(left+right)/;
build(i*,left,mid);
build(i*+,mid,right);
}
void find(int i)
{
if (tree[i].mark>=)
{
tree[i].twice=tree[i].once=tree[i].rf-tree[i].lf;
return;
}
else if (tree[i].mark==)
{
tree[i].once=tree[i].rf-tree[i].lf;
if (tree[i].l+==tree[i].r) tree[i].twice=;
else tree[i].twice=tree[i*].once+tree[i*+].once;
}
else
{
if(tree[i].l+==tree[i].r)
tree[i].once=tree[i].twice=;
else
{
tree[i].once=tree[i*].once+tree[i*+].once;
tree[i].twice=tree[i*].twice+tree[i*+].twice;
}
}
}
void update(int i,node g)
{
//printf("***%d***\n",i);
if (g.y1==tree[i].lf&&g.y2==tree[i].rf)
{
tree[i].mark+=g.flag;
find(i); //更新区间
return ;
}
if (g.y2<=tree[i*].rf) update(i*,g);
else if (g.y1>=tree[i*+].lf) update(i*+,g);
else
{
node temp=g;
temp.y2=tree[i*].rf;
update(i*,temp);
temp=g;
temp.y1=tree[i*+].lf;
update(i*+,temp);
}
find(i);
}
int main()
{
int t,n,i,k;
double x1,x2,y1,y2,ans;
while (~scanf("%d",&k))
{
while (k--)
{
scanf("%d",&n);
t=;
while (n--)
{
scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
num[t].x=x1,num[t].y1=y1,num[t].y2=y2;
num[t].flag=;a[t]=y1;
t++;
num[t].x=x2,num[t].y1=y1,num[t].y2=y2;
num[t].flag=-;a[t]=y2;
t++;
}
sort(num+,num+t,cmp);
sort(a+,a+t);
ans=;
build(,,t-);
//printf("-1\n");
update(,num[]);
for (i=;i<t;i++)
{
ans+=tree[].twice*(num[i].x-num[i-].x);
update(,num[i]);
}
printf("%.2lf\n",ans);
}
}
return ;
}

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

  1. hdu 4419 线段树 扫描线 离散化 矩形面积

    //离散化 + 扫描线 + 线段树 //这个线段树跟平常不太一样的地方在于记录了区间两个信息,len[i]表示颜色为i的被覆盖的长度为len[i], num[i]表示颜色i 『完全』覆盖了该区间几层. ...

  2. 覆盖的面积 HDU - 1255 线段树+扫描线+离散化 求特定交叉面积

    #include<cstdio> #include<map> #include<algorithm> using namespace std; ; struct N ...

  3. hdu 1828 线段树扫描线(周长)

    Picture Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Sub ...

  4. hdu 4052 线段树扫描线、奇特处理

    Adding New Machine Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Othe ...

  5. POJ-1151-Atlantis(线段树+扫描线+离散化)[矩形面积并]

    题意:求矩形面积并 分析:使用线段树+扫描线...因为坐标是浮点数的,因此还需要离散化! 把矩形分成两条边,上边和下边,对横轴建树,然后从下到上扫描上去,用col表示该区间有多少个下边,sum代表该区 ...

  6. hdu1542 线段树扫描线求矩形面积的并

    题意:       给你n个正方形,求出他们的所占面积有多大,重叠的部分只能算一次. 思路:       自己的第一道线段树扫描线题目,至于扫描线,最近会写一个总结,现在就不直接在这里写了,说下我的方 ...

  7. hdu 5091(线段树+扫描线)

    上海邀请赛的一道题目,看比赛时很多队伍水过去了,当时还想了好久却没有发现这题有什么水题的性质,原来是道成题. 最近学习了下线段树扫描线才发现确实是挺水的一道题. hdu5091 #include &l ...

  8. HDU 5107 线段树扫描线

    给出N个点(x,y).每一个点有一个高度h 给出M次询问.问在(x,y)范围内第k小的高度是多少,没有输出-1 (k<=10) 线段树扫描线 首先离散化Y坐标,以Y坐标建立线段树 对全部的点和询 ...

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

    覆盖的面积 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Problem D ...

随机推荐

  1. 学JS的心路历程-JS支持面向对象?(二)

    昨天讲了面向对象的继承,今天我们来谈谈多态和封装吧! 多态polymorphism 抽象讲法解释,就是使用单一界面操作多种型态的物件 继承父类别,定义与父类别中相同的方法,但实作内容不同,称为复写(o ...

  2. InfluxDB时序数据库应用场景

    目前了解到的InfluxDB时序数据库应用场景:如在数据库中有很多条记录,有的记录包含了时间字段time和数值字段water_level,有的只有时间字段time SELECT MAX("w ...

  3. opencv批量修改图片尺寸

    #include"opencv2/opencv.hpp" using namespace std; using namespace cv; #include<opencv2/ ...

  4. matlab stereo_gui立体标定

    http://www.vision.caltech.edu/bouguetj/calib_doc/index.html#examples 文档中举了几个例子,有关双目的是第5个, 这个例子展示了如何使 ...

  5. Linux下开启计划任务日志

    crontab记录日志 修改rsyslog vim /etc/rsyslog.d/50-default.conf (我的是root用户) 搜索cron 把如下行之前的注释"#"去掉 ...

  6. SSM框架下,使用ajax请求上传文件(doc\docx\excel\图片等)

    1.准备工作 1.1.添加上传必要jar包 <dependency> <groupId>commons-io</groupId> <artifactId> ...

  7. 同时启动多个Tomcat 和 Linux部署多个tomcat

    a.减压2份tomcat文件 b.修改其中一个tomcat 的http访问端口(默认为8080端口,这里改为8091) c.修改其中一个tomcat 的Shutdown端口(默认为8005端口,这里改 ...

  8. editplus设置自动换行方法 editplus自动换行设置步骤

    原文链接:https://www.jb51.net/softjc/165897.html 发布时间:2014-05-14 17:03:54   作者:佚名    我要评论 editplus自动换行设置 ...

  9. laravel 自定义常量的方法

    注意:laravel版本为5.1  第一种方法 在本地可以用 我上传到服务器发现用不了  有待解决 第二种方法  在本地可以用 上传服务器后 要把 constants.php   文件权限改为 755 ...

  10. vmware 共享文件夹

    参考 https://jingyan.baidu.com/article/7f766daf7866be4101e1d0ed.html 只是设置共享文件夹选项还不行,需要从安装vmware的安装路径中找 ...