POJ1151Atlantis 矩形面积并[线段树 离散化 扫描线]
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 21734 | Accepted: 8179 |
Description
Input
The input file is terminated by a line containing a single 0. Don't process it.
Output
Output a blank line after each test case.
Sample Input
2
10 10 20 20
15 15 25 25.5
0
Sample Output
Test case #1
Total explored area: 180.00
Source
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
using namespace std;
const int N=;
#define m (l+r)/2
#define lson o<<1,l,m
#define rson o<<1|1,m+1,r
#define lc o<<1
#define rc o<<1|1
inline int read(){
char c=getchar();int x=,f=;
while(c<''||c>''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
}
int n,cnt=;
double x1,y1,x2,y2,mp[N];
struct seg{
double l,r,h;
int f;//1 or -1
seg(double a=,double b=,double c=,int d=):l(a),r(b),h(c),f(d){}
bool operator <(const seg &r)const{return h<r.h;}
}a[N];
struct node{
double sum;
int cov;
}t[N<<];
inline int Bin(double v){
int l=,r=cnt;
while(l<=r){
int mid=(l+r)>>;
if(mp[mid]==v) return mid;
else if(v<mp[mid]) r=mid-;
else l=mid+;
}
return -;
}
inline void pushUp(int o,int l,int r){
if(t[o].cov) t[o].sum=mp[r+]-mp[l];
else if(l==r) t[o].sum=;
else t[o].sum=t[lc].sum+t[rc].sum;
}
void update(int o,int l,int r,int ql,int qr,int v){
if(ql<=l&&r<=qr){
t[o].cov+=v;
pushUp(o,l,r);
}else{
if(ql<=m) update(lson,ql,qr,v);
if(m<qr) update(rson,ql,qr,v);
pushUp(o,l,r);
}
}
int cas=;
int main(int argc, const char * argv[]) {
while((n=read())){
double ans=;
for(int i=;i<=n;i++){
scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
a[i*-]=seg(x1,x2,y1,);
a[i*]=seg(x1,x2,y2,-);
mp[*i-]=x1;
mp[*i]=x2;
}
sort(mp+,mp++*n);
sort(a+,a++*n);
cnt=;mp[++cnt]=mp[];
for(int i=;i<=*n;i++)
if(mp[i]!=mp[i-]) mp[++cnt]=mp[i];
memset(t,,sizeof(t));
for(int i=;i<=*n-;i++){//最后一个不用
int ql=Bin(a[i].l),qr=Bin(a[i].r)-;
if(ql<=qr) update(,,cnt,ql,qr,a[i].f);
ans+=t[].sum*(a[i+].h-a[i].h);
}
printf("Test case #%d\n",++cas);
printf("Total explored area: %.2f\n\n",ans);
} return ;
}
线段树需要插入线段,删除线段,求线段覆盖的总长度,貌似还是用标记永久化比较方便,否则删(我)除(没)很(写)麻(出)烦(来)
注意这个线段树节点是一段区间哦
离散化m忘清0了 WA了几次
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
using namespace std;
const int N=;
#define lson x<<1,l,mid
#define rson x<<1|1,mid+1,r
#define lc x<<1
#define rc x<<1|1
inline int read(){
char c=getchar();int x=,f=;
while(c<''||c>''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
}
int n;
double x1,y1,x2,y2;
struct Seg{
double l,r,y;
int f;
Seg(double l=,double r=,double y=,int f=):l(l),r(r),y(y),f(f){}
bool operator <(const Seg &a)const{return y<a.y;}
}a[N];
double mp[N];int m;
void iniMP(){
sort(mp+,mp++m);
int p=;
mp[++p]=mp[];
for(int i=;i<=m;i++) if(mp[i]!=mp[i-]) mp[++p]=mp[i];
m=p;
}
inline int Bin(double v){
int l=,r=m;
while(l<=r){
int mid=(l+r)>>;
if(v==mp[mid]) return mid;
else if(v<mp[mid]) r=mid-;
else l=mid+;
}
return ;
}
struct node{
double sum;
int cov;
node():sum(),cov(){}
}t[N<<];
void pushUp(int x,int l,int r){
if(t[x].cov) t[x].sum=mp[r+]-mp[l];
else if(l==r) t[x].sum=;
else t[x].sum=t[lc].sum+t[rc].sum;
}
void segCov(int x,int l,int r,int ql,int qr,int v){
if(ql<=l&&r<=qr) t[x].cov+=v,pushUp(x,l,r);
else{
int mid=(l+r)>>;
if(ql<=mid) segCov(lson,ql,qr,v);
if(mid<qr) segCov(rson,ql,qr,v);
pushUp(x,l,r);
}
} int cas=;
int main(int argc, const char * argv[]) {
while((n=read())){
m=;
for(int i=;i<=n;i++){
scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
a[i*-]=Seg(x1,x2,y1,);
a[i*]=Seg(x1,x2,y2,-);
mp[++m]=x1;mp[++m]=x2;
}
iniMP();
n<<=;
sort(a+,a++n);
memset(t,,sizeof(t));
double ans=;
for(int i=;i<=n-;i++){
int ql=Bin(a[i].l),qr=Bin(a[i].r)-;
if(ql<=qr) segCov(,,m,ql,qr,a[i].f);
ans+=t[].sum*(a[i+].y-a[i].y);
}
printf("Test case #%d\n",++cas);
printf("Total explored area: %.2f\n\n",ans);
} return ;
}
POJ1151Atlantis 矩形面积并[线段树 离散化 扫描线]的更多相关文章
- POJ 1151Atlantis 矩形面积并[线段树 离散化 扫描线]
Atlantis Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 21734 Accepted: 8179 Descrip ...
- hdu1542 矩形面积并(线段树+离散化+扫描线)
题意: 给你n个矩形,输入每个矩形的左上角坐标和右下角坐标. 然后求矩形的总面积.(矩形可能相交). 题解: 前言: 先说说做这道题的感受: 刚看到这道题顿时就懵逼了,几何 烂的渣渣.后来从网上搜题解 ...
- poj-1151矩形面积并-线段树
title: poj-1151矩形面积并-线段树 date: 2018-10-30 22:35:11 tags: acm 刷题 categoties: ACM-线段树 概述 线段树问题里的另一个问题, ...
- 【POJ 2482】 Stars in Your Window(线段树+离散化+扫描线)
[POJ 2482] Stars in Your Window(线段树+离散化+扫描线) Time Limit: 1000MS Memory Limit: 65536K Total Submiss ...
- HDU1542 Atlantis —— 求矩形面积并 线段树 + 扫描线 + 离散化
题目链接:https://vjudge.net/problem/HDU-1542 There are several ancient Greek texts that contain descript ...
- Codeforces 610D Vika and Segments 线段树+离散化+扫描线
可以转变成上一题(hdu1542)的形式,把每条线段变成宽为1的矩形,求矩形面积并 要注意的就是转化为右下角的点需要x+1,y-1,画一条线就能看出来了 #include<bits/stdc++ ...
- POJ 1177/HDU 1828 picture 线段树+离散化+扫描线 轮廓周长计算
求n个图矩形放下来,有的重合有些重合一部分有些没重合,求最后总的不规则图型的轮廓长度. 我的做法是对x进行一遍扫描线,再对y做一遍同样的扫描线,相加即可.因为最后的轮廓必定是由不重合的线段长度组成的, ...
- hdu1542线段树+离散化+扫描线
参考博客: http://blog.csdn.net/xingyeyongheng/article/details/8927732 总的来说就是用一条(假想的)线段去平行x轴从下往上扫描,扫描的过程中 ...
- Picture POJ - 1177 线段树+离散化+扫描线 求交叉图像周长
参考 https://www.cnblogs.com/null00/archive/2012/04/22/2464876.html #include <stdio.h> #include ...
随机推荐
- SQL Server:APPLY表运算符
SQL Server 2005(含)以上版本,新增了APPLY表运算,为我们日常查询带来了极大的方便. 新增的APPLY表运算符把右表表达式应用到左表表达式中的每一行.它不像JOIN那样先计算那个表表 ...
- java web学习总结(十四) -------------------JSP原理
一.什么是JSP? JSP全称是Java Server Pages,它和servle技术一样,都是SUN公司定义的一种用于开发动态web资源的技术. JSP这门技术的最大的特点在于,写jsp就像在写h ...
- Javaweb学习笔记——EL表达式
一.前言 EL表达式是什么? 简而言之,可以这样理解,EL表达式全名为:Exprexxsion Language,原先是JSTL 1.0为了方便存取数据而定义的语言,到了JSTL 2.0便正式成为标准 ...
- jquery模拟LCD 时钟
查看效果网址:http://keleyi.com/keleyi/phtml/jqtexiao/24.htm 以下是HTML文件源代码: <!DOCTYPE html PUBLIC "- ...
- 游标的使用——mysql
CREATE DEFINER=`root`@`%` PROCEDURE `split_category_all`()BEGIN declare categ varchar(10); ##套餐列 dec ...
- angular源码分析:angular中脏活累活的承担者之$interpolate
一.首先抛出两个问题 问题一:在angular中我们绑定数据最基本的方式是用两个大括号将$scope的变量包裹起来,那么如果想将大括号换成其他什么符号,比如换成[{与}],可不可以呢,如果可以在哪里配 ...
- 解决jQuery多个版本,与其他js库冲突方法
jQuery多个版本或和其他js库冲突主要是常用的$符号的问题,这个问题 jquery早早就有给我们预留处理方法了,下面一起来看看解决办法. 1.同一页面jQuery多个版本或冲突解决方法. < ...
- collection view 开发笔记
使用collectionView 注册的cell 不会调用 init 方法 会调用 initwith fram 方法.
- Android开发学习——ListView+BaseAdapter的使用
ListView 就是用来显示一行一行的条目的MVC结构 * M:model模型层,要显示的数据 ----people集合 * V:view视图层,用户看到的界面 ...
- Intent属性详解二 Action、Category
先看效果图: 1.Action:该activity可以执行的动作 该标识用来说明这个activity可以执行哪些动作,所以当隐式intent传递过来action时,如果跟这里<intent-fi ...