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. Java基础-SSM之Spring和Mybatis整合案例

    Java基础-SSM之Spring和Mybatis整合案例 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任.   在之前我分享过mybatis和Spring的配置案例,想必大家对它们的 ...

  2. python---django中url访问方法

    只是了解,不推荐使用,毕竟干扰太多,任意冲突,也没有解耦,应该使用路由分发 在url匹配中支持正则匹配,例如: from django.conf.urls import include, urlfro ...

  3. Spark记录-Scala模式匹配

    Scala模式匹配 模式匹配是Scala函数值和闭包后第二大应用功能.Scala为模式匹配提供了极大的支持,处理消息. 模式匹配包括一系列备选项,每个替代项以关键字大小写为单位.每个替代方案包括一个模 ...

  4. 使用 git 托管代码

    1. 下载安装好 git 客户端 2. 找一个家代码托管平台 我用 coding.net,注册个账号,建一个空项目 然后打开安装好的 git bash 客户端,使用 git clone 命令克隆下远程 ...

  5. inline-block的间距问题

    张鑫旭的博客有提到,解决的方法有很多,先贴下,回头再做整理. http://www.zhangxinxu.com/wordpress/2012/04/inline-block-space-remove ...

  6. JavaScript 删除 ASP.NET 设置的多值 Cookie 的方法

    需要注意HttpOnly,Path等属性.完整的测试代码: ASPX 代码<%@ Page Language="C#" %> <!DOCTYPE html PUB ...

  7. 【LibreOJ】#6396. 「THUPC2018」弗雷兹的玩具商店 / Toyshop 线段树+完全背包

    [题目]#6396. 「THUPC2018」弗雷兹的玩具商店 / Toyshop [题意]给定一个长度为n的物品序列,每个物品有价值.不超过m的重量.要求支持以下三种操作:1.物品价值区间加减,2.物 ...

  8. vue路由DEMO

    index.js,index.vue,course.vue,master.vue等 import Vue from 'vue' import Router from 'vue-router' impo ...

  9. 【干货】操纵时间 感受威胁 MAC time时间戳视角

    来源:Unit 4: Unix/Linux Forensics Analysis 4.1 Unix/Linux Forensics Analysis MAC Times Sleuthkit工具的MAC ...

  10. linux根据端口查找进程【原创】

    如转载请注明地址 1.利用lsof -i:端口号 lsof -i:端口号 [root@01 ~]# lsof -i:8097COMMAND PID USER FD TYPE DEVICE SIZE/O ...