Atlantis
Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 21734   Accepted: 8179

Description

There are several ancient Greek texts that contain descriptions of the fabled island Atlantis. Some of these texts even include maps of parts of the island. But unfortunately, these maps describe different regions of Atlantis. Your friend Bill has to know the total area for which maps exist. You (unwisely) volunteered to write a program that calculates this quantity.

Input

The input consists of several test cases. Each test case starts with a line containing a single integer n (1 <= n <= 100) of available maps. The n following lines describe one map each. Each of these lines contains four numbers x1;y1;x2;y2 (0 <= x1 < x2 <= 100000;0 <= y1 < y2 <= 100000), not necessarily integers. The values (x1; y1) and (x2;y2) are the coordinates of the top-left resp. bottom-right corner of the mapped area. 
The input file is terminated by a line containing a single 0. Don't process it.

Output

For each test case, your program should output one section. The first line of each section must be "Test case #k", where k is the number of the test case (starting with 1). The second one must be "Total explored area: a", where a is the total explored area (i.e. the area of the union of all rectangles in this test case), printed exact to two digits to the right of the decimal point. 
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


[10-13-2016]
有一条线从下往上扫,维护当前的x轴覆盖总长度
#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 ;
}
 

POJ 1151Atlantis 矩形面积并[线段树 离散化 扫描线]的更多相关文章

  1. POJ1151Atlantis 矩形面积并[线段树 离散化 扫描线]

    Atlantis Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 21734   Accepted: 8179 Descrip ...

  2. POJ 1177/HDU 1828 picture 线段树+离散化+扫描线 轮廓周长计算

    求n个图矩形放下来,有的重合有些重合一部分有些没重合,求最后总的不规则图型的轮廓长度. 我的做法是对x进行一遍扫描线,再对y做一遍同样的扫描线,相加即可.因为最后的轮廓必定是由不重合的线段长度组成的, ...

  3. hdu1542 矩形面积并(线段树+离散化+扫描线)

    题意: 给你n个矩形,输入每个矩形的左上角坐标和右下角坐标. 然后求矩形的总面积.(矩形可能相交). 题解: 前言: 先说说做这道题的感受: 刚看到这道题顿时就懵逼了,几何 烂的渣渣.后来从网上搜题解 ...

  4. poj-1151矩形面积并-线段树

    title: poj-1151矩形面积并-线段树 date: 2018-10-30 22:35:11 tags: acm 刷题 categoties: ACM-线段树 概述 线段树问题里的另一个问题, ...

  5. 【POJ 2482】 Stars in Your Window(线段树+离散化+扫描线)

    [POJ 2482] Stars in Your Window(线段树+离散化+扫描线) Time Limit: 1000MS   Memory Limit: 65536K Total Submiss ...

  6. POJ 2528 Mayor's posters(线段树+离散化)

    Mayor's posters 转载自:http://blog.csdn.net/winddreams/article/details/38443761 [题目链接]Mayor's posters [ ...

  7. poj 2528 Mayor's posters 线段树+离散化技巧

    poj 2528 Mayor's posters 题目链接: http://poj.org/problem?id=2528 思路: 线段树+离散化技巧(这里的离散化需要注意一下啊,题目数据弱看不出来) ...

  8. HDU1542 Atlantis —— 求矩形面积并 线段树 + 扫描线 + 离散化

    题目链接:https://vjudge.net/problem/HDU-1542 There are several ancient Greek texts that contain descript ...

  9. poj 2528 Mayor's posters 线段树+离散化 || hihocode #1079 离散化

    Mayor's posters Description The citizens of Bytetown, AB, could not stand that the candidates in the ...

随机推荐

  1. Hadoop生态圈-Kafka的新API实现生产者-消费者

         Hadoop生态圈-Kafka的新API实现生产者-消费者 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任.

  2. <meta content='IE=edge,chrome=1' http-equiv='X-UA-Compatible' />

    代码一:<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> http-eq ...

  3. 快速了解yuv4:4:4 yuv4:2:2 yuv 4:1:1 yuv 4:2:0四种YUV格式区别

    四种YUV格式区别如下: 1.YUV  4:4:4抽样方式: Y: Y0 Y1 Y2 Y3 U: U0 U1 U2 U3 V: V0 V1 V2 V3 2.YUV   4:2:2抽样方式: Y   : ...

  4. HDU 3595 every-sg模型

    多个子游戏同时进行,每个子游戏给出两个数a,b,可以将大的数减去k倍小的数,不能操作者输. 策略就是对于一个必胜的游戏要使得步数更长,对于一个必败的游戏使得步数最短. 以下都来自贾志豪的论文.. 对于 ...

  5. Struts2_day03

    一.上节回顾 1 在action获取表单提交数据 (1)使用ActionContext类获取 (2)使用ServletActionContext类获取 (3)接口注入 2 结果配置 (1)全局结果页面 ...

  6. 一致性哈希算法介绍,及java实现

    应用场景 在做服务器负载均衡时候可供选择的负载均衡的算法有很多,包括: 轮循算法(Round Robin).哈希算法(HASH).最少连接算法(Least Connection).响应速度算法(Res ...

  7. [转载]DOMContentLoaded与interactive

    http://www.cnblogs.com/muxrwc/archive/2011/01/13/1934379.html ie中inline script执行时竟然第一次进入页面,doc.ready ...

  8. 在C#中使用.NET SDK创建控制

    下载示例工程 - 8 Kb 介绍 在这篇教程中,我将使用.NET架构创建一个简单的时钟控制示例,这个控制是一个显示当前时间的时钟,我将指导读者实现秒针并显示钟点数.文章加亮处是创建这个控制的关键点,读 ...

  9. HTML5 移动开发(CSS3设计移动页面样式)

    1.如何创建CSS样式表 2.CSS3的卓越特性 3.基于设备属性改变样式的媒体查询 4.如何使用属性改变元标签创建更美观移动页面   层叠样式表是移动WEB开发中的一个重要组成部分,本次分享将学到如 ...

  10. Sql语句 表中相同的记录(某个字段)只显示一条,按照时间排序显示最大或最小

    原始表数据: