浅谈树状数组与线段树:https://www.cnblogs.com/AKMer/p/9946944.html

题目传送门:https://www.lydsy.com/JudgeOnline/problem.php?id=1382

扫描线模板题。假设有一条直线从左往右扫过平面,那么每一单位时间内这条直线被矩形覆盖的长度的和就是矩形们的面积。而直线上被覆盖的长度只会在经过矩阵的竖边时发生变化,当我们扫到一条矩阵的左边时就在该左边所覆盖的区间上打标记表示这一段区间已经被覆盖,扫到右边时减掉。一共有\(2*n\)条边,也就一共有\(2*n-1\)个区间,每个区间的面积就是当前直线上被覆盖的长度乘以构成这个区间的两条线段的\(x\)轴差值。

我们将\(2*n\)条边按\(x\)轴坐标排序,每条线段的\(y\)轴坐标离散化,然后用线段树维护每个\(y\)轴上的区间被多少条线段覆盖了。如果区间[\(l,r\)](意思是第\(l\)条线段到第\(r+1\)条线段构成的区间)被覆盖的次数大于\(0\),那么这一段的线段被覆盖的长度就是\(y[r+1]-y[l]\),否则就由两个儿子节点更新过来。因为边都是成对出现的,所以覆盖标记不用下传。

每次直接用根节点的覆盖长度乘以两条线段的\(x\)坐标的差值累加面积即可。

时间复杂度:\(O(nlogn)\)

空间复杂度:\(O(n)\)

代码如下:

#include <cstdio>
#include <algorithm>
using namespace std;
typedef long long ll; const int maxn=2e4+5; ll ans;
int n,cnt;
int tmp[maxn]; 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*10+ch-'0';
return x*f;
} struct line {
int x,st,ed,mark; line() {} line(int _x,int _st,int _ed,int _mark) {
x=_x,st=_st,ed=_ed,mark=_mark;
} bool operator<(const line &a)const {
return x<a.x;
}
}p[maxn]; struct segment_tree {
int len[maxn<<2],cnt[maxn<<2]; void updata(int p,int l,int r) {
if(cnt[p])len[p]=tmp[r+1]-tmp[l];//如果有被线段覆盖就直接加进全部长度
else if(l==r)len[p]=0;//如果是叶子节点就等于0,
else len[p]=len[p<<1]+len[p<<1|1];//否则用儿子更新
} void change(int p,int l,int r,int L,int R,int v) {
if(L<=l&&r<=R) {
cnt[p]+=v;
updata(p,l,r);//每次覆盖都需要更新
return;
}
int mid=(l+r)>>1;
if(L<=mid)change(p<<1,l,mid,L,R,v);
if(R>mid)change(p<<1|1,mid+1,r,L,R,v);
updata(p,l,r);
}
}T; int main() {
n=read();
for(int i=1;i<=n;i++) {
int x1=read(),y1=read(),x2=read(),y2=read();
tmp[(i<<1)-1]=y1,tmp[i<<1]=y2;
p[(i<<1)-1]=line(x1,y1,y2,1);
p[i<<1]=line(x2,y1,y2,-1);
}sort(p+1,p+2*n+1);sort(tmp+1,tmp+2*n+1);
cnt=unique(tmp+1,tmp+2*n+1)-tmp-1;
for(int i=1;i<=2*n;i++) {
p[i].st=lower_bound(tmp+1,tmp+cnt+1,p[i].st)-tmp;
p[i].ed=lower_bound(tmp+1,tmp+cnt+1,p[i].ed)-tmp;
}//排序和离散化
for(int i=1;i<=2*n;i++) {
ans+=1ll*T.len[1]*(p[i].x-p[i-1].x);//累加第i-1号区间的面积
T.change(1,1,cnt-1,p[i].st,p[i].ed-1,p[i].mark);//更新直线上被覆盖的长度
}printf("%lld\n",ans);
return 0;
}

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

  1. bzoj1382: [Baltic2001]Mars Maps

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

  2. SQL Server 2008空间数据应用系列八:基于Bing Maps(Silverlight)的空间数据存储

    原文:SQL Server 2008空间数据应用系列八:基于Bing Maps(Silverlight)的空间数据存储 友情提示,您阅读本篇博文的先决条件如下: 1.本文示例基于Microsoft S ...

  3. SQL Server 2008空间数据应用系列七:基于Bing Maps(Silverlight) 的空间数据展现

    原文:SQL Server 2008空间数据应用系列七:基于Bing Maps(Silverlight) 的空间数据展现 友情提示,您阅读本篇博文的先决条件如下: 1.本文示例基于Microsoft ...

  4. 【Silverlight】Bing Maps学习系列(八):使用Bing Maps Silverlight Control加载自己部署的Google Maps

    [Silverlight]Bing Maps学习系列(八):使用Bing Maps Silverlight Control加载自己部署的Google Maps 上个月微软必应地图(Bing Maps) ...

  5. 【Silverlight】Bing Maps学习系列(七):使用Bing Maps的图片系统(Tile System)

    [Silverlight]Bing Maps学习系列(七):使用Bing Maps的图片系统(Tile System) 目前包括微软必应地图在内的几乎所有在线电子地图(如:Google Maps等)都 ...

  6. 【Silverlight】Bing Maps学习系列(二):通过Bing Maps Silverlight Control如何显示地图(转)

    [Silverlight]Bing Maps学习系列(二):通过Bing Maps Silverlight Control如何显示地图 如本系列第一篇你所介绍的,开发基于Silverlight的Bin ...

  7. Bing Maps进阶系列八:在Bing Maps中集成OpenStreetMap地图

    Bing Maps进阶系列八:在Bing Maps中集成OpenStreetMap地图 OSM(OpenStreetMap-开放街道地图)服务就是一种发布自己地图数据图片为服务的一种实现类型,开放街道 ...

  8. Bing Maps进阶系列一:初识Bing Maps地图服务

    Bing Maps进阶系列一:初识Bing Maps地图服务 Bing Maps提供了一组WCF的地图服务,使用这些服务我们可以方便的在自己的应用系统里实现地理位置搜索等相关功能.他们分别是地理编码服 ...

  9. [BZOJ1382]Mars Maps

    Description In the year 2051, several Mars expeditions have explored different areas of the red plan ...

随机推荐

  1. linux脚本实现自己主动输入password

    使用Linux的程序猿对输入password这个举动一定不陌生,在Linux下对用户有严格的权限限制,干非常多事情越过了权限就得输入password.比方使用超级用户运行命令,又比方ftp.ssh连接 ...

  2. HTML5 2D平台游戏开发#2跳跃与二段跳

    在上一篇<Canvas制作时间与行为可控的sprite动画>中已经实现了角色的左右移动,本篇继续实现角色的一系列动作之一:跳跃.先来看看最终效果: 要实现跳跃,必须模拟垂直方向的速度和重力 ...

  3. ReentrentLock重入锁

    ReentrentLock lock=new ReentrentLock(); lock.lock(); //锁的代码 finally{ lock.unlock(); } ReentrentLock ...

  4. HDFS源码分析心跳汇报之BPServiceActor工作线程运行流程

    在<HDFS源码分析心跳汇报之数据结构初始化>一文中,我们了解到HDFS心跳相关的BlockPoolManager.BPOfferService.BPServiceActor三者之间的关系 ...

  5. Linux系统调用及用户编程接口(API)

    系统调用 所谓系统调用是指操作系统提供给用户程序调用的一组"特殊"接口,用户程序能够通过这组"特殊"接口来获得操作系统内核提供的服务.比如用户能够通过进程控制相 ...

  6. java 给多人发送、抄送

    关键技术: 1.MimeMessage的setRecipients方法设置邮件的收件人,其中Message.RecipientType.TO常量表示收件人类型是邮件接收者,Message.Recipi ...

  7. WCF基础之配置服务

    在WCF应用编程中配置服务是其主要部分. 配置可以定义和自定义如何向客户端公开服务,包括服务地址,发送和接受消息的传输和编码,以及服务的安全类型. 服务的配置有两种:编码和使用config文件,大多数 ...

  8. vue如何做分页?

    原创作品转载请注明出处 先来看一下效果图:    功能描述: 1. 点击页面序号跳转到相应页面: 2. 点击单左/单右,向后/向前跳转一个页面: 3. 点击双左/双右,直接跳转到最后一页/第一页: 3 ...

  9. Android笔记之使用ImageView加载网络图片以及保存图片到本地并更新图库

    ImageView显示网络图片 findViewById(R.id.btnLoad).setOnClickListener(new View.OnClickListener() { @Override ...

  10. java读取TXT文件中的数据

    将文件放在一个指定的磁盘目录下: File file = new File("指定的文件路径"); try{ BufferedReader br = new BufferedRea ...