【 HDU 1255】 覆盖的面积(矩阵面积交,线段树,扫描法)
【题目】
覆盖的面积
Problem Description给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积.
Input输入数据的第一行是一个正整数T(1<=T<=100),代表测试数据的数量.每个测试数据的第一行是一个正整数N(1<=N<=1000),代表矩形的数量,然后是N行数据,每一行包含四个浮点数,代表平面上的一个矩形的左上角坐标和右下角坐标,矩形的上下边和X轴平行,左右边和Y轴平行.坐标的范围从0到100000.注意:本题的输入数据较多,推荐使用scanf读入数据.
Output对于每组测试数据,请计算出被这些矩形覆盖过至少两次的区域的面积.结果保留两位小数.Sample Input2
5
1 1 4 2
1 3 3 7
2 1.5 5 4.5
3.5 1.25 7.5 4
6 3 10 7
3
0 0 1 1
1 0 2 1
2 0 3 1Sample Output7.63
0.00AuthorIgnatius.L & weigang Lee
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
#define Maxn 100010 struct hp
{
int x1,x2,flag;
double y;
}t[Maxn*];int tl;
struct lsh
{
double x;
int id;
}q[Maxn*];int ql; bool cmp(lsh x,lsh y) {return x.x<y.x;}
bool cmp2(hp x,hp y) {return x.y<y.y;} int mymin(int x,int y) {return x<y?x:y;} double dis[*Maxn]; struct node
{
int l,r,lc,rc,cnt;
double sm,fg;
}tr[Maxn*];int len;
int build(int l,int r)
{
int x=++len;
tr[x].l=l;tr[x].r=r;
tr[x].sm=tr[x].cnt=;tr[x].fg=;
if(l<r-)
{
int mid=(tr[x].l+tr[x].r)>>;
tr[x].lc=build(l,mid);
tr[x].rc=build(mid,r);
}
else tr[x].lc=tr[x].rc=;
return x;
} void upd(int x)
{
int l=tr[x].l,r=tr[x].r,lc=tr[x].lc,rc=tr[x].rc;
if(tr[x].cnt!=) tr[x].fg=dis[r]-dis[l];
else tr[x].fg=tr[lc].fg+tr[rc].fg;
if(tr[x].cnt>=) tr[x].sm=dis[r]-dis[l];
else if(tr[x].cnt==) tr[x].sm=tr[lc].fg+tr[rc].fg;
else tr[x].sm=tr[lc].sm+tr[rc].sm;
} void change(int x,int l,int r,int c)
{
if(tr[x].l==l&&tr[x].r==r)
{
tr[x].cnt+=c;
upd(x);
return;
}
int mid=(tr[x].l+tr[x].r)>>;
if(r<=mid) change(tr[x].lc,l,r,c);
else if(l>=mid) change(tr[x].rc,l,r,c);
else
{
change(tr[x].lc,l,mid,c);
change(tr[x].rc,mid,r,c);
}
upd(x);
} int main()
{
int T;
int n;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
if(n==) break;
tl=;ql=;
for(int i=;i<=n;i++)
{
double x1,y1,x2,y2;
scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
//t[++tl].x1,
t[++tl].flag=;t[tl].y=y1;
t[++tl].flag=-;t[tl].y=y2;
q[++ql].x=x1,q[ql].id=tl;
q[++ql].x=x2,q[ql].id=tl+*n;
}
sort(q+,q++ql,cmp);
int p=;
for(int i=;i<=ql;i++)
{
if(q[i].x!=q[i-].x||p==) p++,dis[p]=dis[p-]+q[i].x-q[i-].x;
if(q[i].id<=*n) t[q[i].id].x1=t[q[i].id-].x1=p;
else t[q[i].id-*n].x2=t[q[i].id--*n].x2=p;
}
sort(t+,t++tl,cmp2);
len=;tr[].sm=;
build(,p);
double ans=;
for(int i=;i<tl;i++)
{
// printf("%d %d\n",t[i].x1,t[i].x2);
change(,t[i].x1,t[i].x2,t[i].flag);
ans+=tr[].sm*(t[i+].y-t[i].y);
}
printf("%.2lf\n",ans);
// printf("Test case #%d\nTotal explored area: %.2lf\n\n",++kase,ans);
}
return ;
}
2016-11-10 14:37:49
【 HDU 1255】 覆盖的面积(矩阵面积交,线段树,扫描法)的更多相关文章
- hdu1255 矩阵的交 线段树+扫描线
/* 不是叶子节点 ,且cnt=1.注意这里,cnt=1确切的意义是什么, 应该是,可以确定,这个区间被完全覆盖了1次, 而有没有被完全覆盖两次或以上则不知道无法确定,那么怎么怎么办了, 只要加上t[ ...
- hdu 1255 覆盖的面积(线段树 面积 交) (待整理)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1255 Description 给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积. In ...
- HDU - 1255 覆盖的面积(线段树求矩形面积交 扫描线+离散化)
链接:线段树求矩形面积并 扫描线+离散化 1.给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积. 2.看完线段树求矩形面积并 的方法后,再看这题,求的是矩形面积交,类同. 求面积时,用被覆 ...
- hdu 1255 覆盖的面积(求覆盖至少两次以上的面积)
了校赛,还有什么途径可以申请加入ACM校队? 覆盖的面积 Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K ...
- hdu 5700区间交(线段树)
区间交 Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submiss ...
- hdu 5266 pog loves szh III(lca + 线段树)
I - pog loves szh III Time Limit:6000MS Memory Limit:131072KB 64bit IO Format:%I64d & %I ...
- HDU 2795 Billboard(宣传栏贴公告,线段树应用)
HDU 2795 Billboard(宣传栏贴公告,线段树应用) ACM 题目地址:HDU 2795 Billboard 题意: 要在h*w宣传栏上贴公告,每条公告的高度都是为1的,并且每条公告都要 ...
- HDU 1255 覆盖的面积 (线段树扫描线+面积交)
自己YY了一个的写法,不过时间复杂度太高了,网上的想法太6了 题意:给你一些矩阵,求出矩阵的面积并 首先按照x轴离散化线段到线段树上(因为是找连续区间,所以段建树更加好做). 然后我们可以想一下怎样 ...
- hdu 1255 覆盖的面积 (扫描线求矩形交)
覆盖的面积 Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Subm ...
- hdu 1255 覆盖的面积 (线段树处理面积覆盖问题(模板))
http://acm.hdu.edu.cn/showproblem.php?pid=1255 覆盖的面积 Time Limit: 10000/5000 MS (Java/Others) Memo ...
随机推荐
- WPF翻转动画
在WPF中要翻转对象,估计是得用三维变换,所以我用到了AxisAngleRotation3D,让图形绕着Z轴来旋转. 先看看效果. 是的,就是这样的效果,在XAML中,由于涉及三维图形,我先做了两个用 ...
- Nginx高性能服务器安装、配置、运维 (6) —— Nginx日志及日志分割
七.Nginx日志及日志分割 (1)Nginx日志文件 查看Nginx配置文件: 找到access_log,yum安装默认存储在/var/log/nginx目录下,且默认main格式: main格式定 ...
- 安卓SQLite数据库操作,半小时开发新闻管理系统,纯干货
本教程致力于可以快速的学习安卓软件开发,希望能通过一系列自己手写的教程,帮助正在学习或想要学习安卓开发的同仁. 本教程由今日头条-全栈攻城狮号首发,都是一个字一个字码的.请尊重劳动成果,转载请注明出处 ...
- Maven 私服的使用实战
本日志主要是介绍下面的配置 1. 将内部构件部署到私服 在工程的pom文件中添加下面配置 <distributionManagement> <repository> <i ...
- SharePoint 文档库实现文件夹拖放到文档库
打开文档库-> 选择文件夹-> 在Ribbon中选择“库(list)”-> 在右边可以看到打开方式-> 选择用资源管理器打开-> 在新打开的资源管理器中可能实现对文夹的拖 ...
- 使用instsrv.exe+srvany.exe将应用程序安装为windows服务[转]
转自:http://qingmu.blog.51cto.com/4571483/1248649 一.什么是instsrv.exe和srvany.exe instsrv.exe.exe和srvany ...
- Ext.Net学习笔记03:Ext.Net MessageBus用法
发布和订阅消息 Ext.Net MessageBus 的本质是一个消息订阅机制,ExtJS中没有这种机制,所以MessageBus的Ext.Net实现的,但并不是原创,这种功能在dojo中早就实现了, ...
- CSS常见选择器
一.元素选择器 p,html,h1, h2 1.多个元素一起设置同一种风格, 则用逗号“,”隔开(选择器分组) 2.通配符选择, *{Color:red} 表示文档中所有元素都为红色 二.类选择器 ...
- 关于Debug下的Log打印问题
在项目中为了调试经常会用到Log打印,比如打印当前方法__func__, 对象,地址等等,所以项目最后每次运行调试控制台满满的都是打印日志,到release发布的时候,显然不太合适,这里其实可以用一个 ...
- ios专题 -block用法
what is block Blocks are a language-level feature added to C, Objective-C and C++, which allow you t ...
