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 ;
}
 

最新文章

  1. Python 随机数生成总结
  2. intel82599在centos6.5下编译安装
  3. swift block
  4. [转载]基于TFS实践敏捷-工作项跟踪
  5. IOS应用程序生命周期的AppDelegate详解
  6. jQuery 关于 end() 方法的详细解释
  7. 用于分类的决策树(Decision Tree)-ID3 C4.5
  8. 【阿里云产品公测】阿里云ACE部署通用完整教程及评测
  9. ReactNative学习-滑动查看图片第三方组件react-native-swiper
  10. MyCat 主键ID自增长配置
  11. Vimperator技巧
  12. GuideActivity.java引导界面:
  13. BSA Network Shell系列-nlogin命令
  14. Python基础学习篇章三
  15. 阅读spring源码
  16. R leaflet
  17. 学习笔记(一)HTML基础
  18. 「AtCoder Grand018B」Sports Festival(暴力)
  19. 【BZOJ2829】[SHOI2012]信用卡凸包(凸包)
  20. GNU Screen Usage

热门文章

  1. python+正态分布+蒙特卡洛预测男女身高概率!
  2. Scala进阶之路-为什么要学习Scala以及开发环境搭建
  3. linux离线部署redis及redis.conf详解
  4. HDU 4509 湫湫系列故事——减肥记II (简单模拟)
  5. c++刷题(37/100)笔试题2
  6. F. Ivan and Burgers(线性基,离线)
  7. 基于滑动窗口协议写的程序(UDP实现) .
  8. RPM Database
  9. innobackupex不停库的数据备份并恢复到别的服务器上【转】
  10. 开启@EnableRedisHttpSession