Description

In the year 2051, several Mars expeditions have explored different areas of the red planet and produced maps of these areas. Now, the BaSA (Baltic Space Agency) has an ambitious plan: they would like to produce a map of the whole planet. In order to calculate the necessary effort, they need to know the total size of the area for which maps already exist. It is your task to write a program that calculates this area.

Task Write a program that:

  • reads the description of map shapes from the input file mar.in,
  • computes the total area covered by the maps,
  • writes the result to the output file mar.out.

题目大意:给你N个矩形,给出矩形对角坐标,要你求出这些矩形所覆盖的面积

Input

The input file mar.in starts with a line containing a single integer N (1<=N<=10 000) the number of available maps. Each of the following N lines describes a map. Each of these lines contains four integers x1, y1, x2 and y2 (0<=x1the coordinates of, respectively, the bottom-left and the top-right corner of the mapped area. Each map has rectangular shape, and its sides are parallel to the x- and y-axis of the coordinate system.

Output

The output should contain one integer A, the total explored area

(i.e. the area of the union of all rectangles).

Sample Input

2

10 10 20 20

15 15 25 30

Sample Output

225


这道题目是一个比较经典的题目,它用到了线段树扫描线这个方法。

扫描线是什么东西?

首先我们给出一张图,图中共有3个矩形,覆盖的总面积为24。



图中绿色的线即为扫描线。线段树上维护的信息为扫描线上的区间是否被覆盖。

扫描线从左方向右方移动,图中红色的边叫做起始边,黄色的边叫做终止边。在扫描线不断扫描的过程中,碰到起始边,我们就将起始边覆盖上去;碰到终止边时,就从扫描线上将其抹去。

这样做有什么用?



我们把关建边(起始边和终止边的统称)所在的位置标明出来。每两个关建边之间都有一段面积(图中相同颜色的为同一段),这些面积之和即为总覆盖面积。这些面积怎么算?

其实相信大家心中已经有了答案。

每一小段的面积,就是上一个关建边操作完之后,线段树上覆盖区间大小乘上两个关建边之间的距离。

所以接下来就是傻逼的处理和线段树的维护了。

#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define inf 0x7f7f7f7f
using namespace std;
typedef long long ll;
typedef unsigned int ui;
typedef unsigned long long ull;
inline int read(){
int x=0,f=1;char ch=getchar();
for (;ch<'0'||ch>'9';ch=getchar()) if (ch=='-') f=-1;
for (;ch>='0'&&ch<='9';ch=getchar()) x=(x<<1)+(x<<3)+ch-'0';
return x*f;
}
inline void print(int x){
if (x>=10) print(x/10);
putchar(x%10+'0');
}
const int N=5e4;
struct AC{
int l,r,val,ID;
bool operator <(const AC &x)const{return val!=x.val?val<x.val:ID>x.ID;}//按横坐标排序,起始边要摆在终止边之前。至于为什么,见文章底
}A[N];
struct Segment{
#define ls (p<<1)
#define rs (p<<1|1)
int tree[N*16+10],Lazy[N*16+10];//线段树记录的就是一个个区间,而不是一个个坐标,因此主程序中使用r-1
void updata(int p,int l,int r){//区间覆盖大小的维护
if (Lazy[p]) tree[p]=r-l+1;
else tree[p]=(l==r)?0:(tree[ls]+tree[rs]);
}
void change(int p,int l,int r,int x,int y,int t){//简单打标记
if (x<=l&&r<=y){
Lazy[p]+=t;
updata(p,l,r);
return;
}
int mid=(l+r)>>1;
if (x<=mid) change(ls,l,mid,x,y,t);
if (y>mid) change(rs,mid+1,r,x,y,t);
updata(p,l,r);
}
}T;
int main(){
int n=read(),ans=0;
for (int i=1;i<=n;i++){
int a=read(),b=read(),c=read(),d=read();
A[i].ID=1,A[i+n].ID=-1;//ID记录是起始边还是结束边
A[i].val=a, A[i].l=b, A[i].r=d-1;//按关建边的x坐标排序,因此要记录,l,r即为区间左右边界
A[i+n].val=c,A[i+n].l=b,A[i+n].r=d-1;
}
sort(A+1,A+1+2*n);
for (int i=1;i<=2*n;i++){
if (i!=1) ans+=(A[i].val-A[i-1].val)*T.tree[1];//i=1的时候没有什么东西可以加
T.change(1,-N,N,A[i].l,A[i].r,A[i].ID);
}
printf("%d\n",ans);
return 0;
}

为什么在排序的时候,起始边要在终止边前面呢?

其实对于本题而言,并没有什么影响。

不过起始边和终止边的摆放位置对下一题有影响。

请参考[IOI1998]Picture

[BZOJ1382]Mars Maps的更多相关文章

  1. bzoj1382: [Baltic2001]Mars Maps

    Description 给出N个矩形,N<=10000.其坐标不超过10^9.求其面积并 Input 先给出一个数字N,代表有N个矩形. 接下来N行,每行四个数,代表矩形的坐标. Output ...

  2. BZOJ1382:[Baltic2001]Mars Maps

    浅谈树状数组与线段树:https://www.cnblogs.com/AKMer/p/9946944.html 题目传送门:https://www.lydsy.com/JudgeOnline/prob ...

  3. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  4. [IOI1998]Picture

    Description 在一个平面上放置一些矩形,所有的边都为垂直或水平.每个矩形可以被其它矩形部分或完全遮盖,所有矩形合并成区域的边界周长称为轮廓周长. 要求:计算轮廓周长. 数据规模: 0≤矩形数 ...

  5. How to Tell Science Stories with Maps

    Reported Features How to Tell Science Stories with Maps August 25, 2015   Greg Miller This map, part ...

  6. 【腾讯Bugly干货分享】微信终端跨平台组件 Mars 系列 - 我们如约而至

    导语 昨天上午,微信在广州举办了微信公开课Pro.于是,精神哥这两天的朋友圈被小龙的"八不做"刷屏了.小伙伴们可能不知道,下午,微信公开课专门开设了技术分论坛.在分论坛中,微信开源 ...

  7. 【腾讯Bugly干货分享】微信终端跨平台组件 mars 系列(二) - 信令传输超时设计

    本文来自于腾讯Bugly公众号(weixinBugly),未经作者同意,请勿转载,原文地址:http://mp.weixin.qq.com/s/9DJxipJaaBC8yC-buHgnTQ 作者简介: ...

  8. 如约而至:微信自用的移动端IM网络层跨平台组件库Mars已正式开源

    1.前言 关于微信内部正在使用的网络层封装库Mars开源的消息,1个多月前就已满天飞(参见<微信Mars:微信内部正在使用的网络层封装库,即将开源>),不过微信团队没有失约,微信Mars ...

  9. 检索Google Maps地图位置(小训练)

    名称:检索地图位置 内容:地图初期显示和检索显示 功能:根据条件检索地图的经度与纬度 1.在这之前我们需要创建一个表(Accoun__c),添加一个重要的字段地理位置情報,它会默认的给你两个字段经度和 ...

随机推荐

  1. 【SQL Server 学习系列】-- ConnectionTimeout、CommandTimeout和BulkCopyTimeout

    1. SqlConnection.ConnectionTimeout获取在尝试建立连接时终止尝试并生成错误之前所等待的时间.单位:秒默认值:15秒设置为0时,表示无限制 2. SqlCommand.C ...

  2. markdown 插入latex公式练习

    markdown 插入latex公式 $$公式$$表示行间公式,本来Tex中使用\(公式\)表示行内公式,但因为Markdown中\是转义字符,所以在Markdown中输入行内公式使用\\(公式\\) ...

  3. ubuntu16.04LTS安装软件

    1.安装chrome 下载源加入到系统的源列表 sudo wget http://www.linuxidc.com/files/repo/google-chrome.list -P /etc/apt/ ...

  4. 【求建议】毕业之声——信院IT类毕业学子经验分享交流会

    一:缘由 在和非常多学子交流,及上课的经历中,发现一个非常普遍的现象:部分大一学生即失去了对学习.对专业的兴趣.有人在迷茫之后奋起直追.从而珍惜利用不多的大学时光努力提高自己.有人在迷茫中沉沦,沉迷于 ...

  5. OO模式-Composite

    组合模式也叫做"部分-总体"模式,这样事实上定义也就非常明显了,正好和数据结构的知识相相应.把对象组合成树形结构以表示"部分-总体"的层次结构. 先看类图: w ...

  6. 在线生成32位和16位大小写MD5密文

    MD5是一种不可逆的加密算法,全称是Message-Digest Algorithm 5(信息-摘要算法).是当前计算机领域用于确保信息传输完整一致而广泛使用的散列算法之一. MD5的典型应用是对一段 ...

  7. 关于mybatis的 insert into select 命令未结束问题

    关于mybatis的 insert into select 命令未结束问题,最后以为是sql写错了,可是,在plsql运行又没问题.最后还是解决这个问题. 是设置问题. ### Cause: java ...

  8. [办公自动化]chrome浏览器的书签在哪里存放

    最近换电脑了. 硬盘直接挂在了新电脑上.忘记导出Chrome的浏览器的书签了. 对于书签,Windows XP和Windows 7的路径都是: C:\Documents and Settings\** ...

  9. myqsl02

    常用的表的引擎 Myisam ,批量插入速度快, 不支持事务,锁表 Innodb, 批量插入相对较慢,支持事务,锁行. 全文索引:目前5.5版本,myisam,innodb都已经支持 关于事务的引擎: ...

  10. UICollectionView基础/UICollectionViewCell的四种创建方式

    前言 UICollectionViewCell的四种创建方式:http://blog.csdn.net/ZC_Huang/article/details/52002302 这个控件,看起来与UITab ...