浅谈树状数组与线段树: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)\)

代码如下:

  1. #include <cstdio>
  2. #include <algorithm>
  3. using namespace std;
  4. typedef long long ll;
  5. const int maxn=2e4+5;
  6. ll ans;
  7. int n,cnt;
  8. int tmp[maxn];
  9. int read() {
  10. int x=0,f=1;char ch=getchar();
  11. for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
  12. for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
  13. return x*f;
  14. }
  15. struct line {
  16. int x,st,ed,mark;
  17. line() {}
  18. line(int _x,int _st,int _ed,int _mark) {
  19. x=_x,st=_st,ed=_ed,mark=_mark;
  20. }
  21. bool operator<(const line &a)const {
  22. return x<a.x;
  23. }
  24. }p[maxn];
  25. struct segment_tree {
  26. int len[maxn<<2],cnt[maxn<<2];
  27. void updata(int p,int l,int r) {
  28. if(cnt[p])len[p]=tmp[r+1]-tmp[l];//如果有被线段覆盖就直接加进全部长度
  29. else if(l==r)len[p]=0;//如果是叶子节点就等于0,
  30. else len[p]=len[p<<1]+len[p<<1|1];//否则用儿子更新
  31. }
  32. void change(int p,int l,int r,int L,int R,int v) {
  33. if(L<=l&&r<=R) {
  34. cnt[p]+=v;
  35. updata(p,l,r);//每次覆盖都需要更新
  36. return;
  37. }
  38. int mid=(l+r)>>1;
  39. if(L<=mid)change(p<<1,l,mid,L,R,v);
  40. if(R>mid)change(p<<1|1,mid+1,r,L,R,v);
  41. updata(p,l,r);
  42. }
  43. }T;
  44. int main() {
  45. n=read();
  46. for(int i=1;i<=n;i++) {
  47. int x1=read(),y1=read(),x2=read(),y2=read();
  48. tmp[(i<<1)-1]=y1,tmp[i<<1]=y2;
  49. p[(i<<1)-1]=line(x1,y1,y2,1);
  50. p[i<<1]=line(x2,y1,y2,-1);
  51. }sort(p+1,p+2*n+1);sort(tmp+1,tmp+2*n+1);
  52. cnt=unique(tmp+1,tmp+2*n+1)-tmp-1;
  53. for(int i=1;i<=2*n;i++) {
  54. p[i].st=lower_bound(tmp+1,tmp+cnt+1,p[i].st)-tmp;
  55. p[i].ed=lower_bound(tmp+1,tmp+cnt+1,p[i].ed)-tmp;
  56. }//排序和离散化
  57. for(int i=1;i<=2*n;i++) {
  58. ans+=1ll*T.len[1]*(p[i].x-p[i-1].x);//累加第i-1号区间的面积
  59. T.change(1,1,cnt-1,p[i].st,p[i].ed-1,p[i].mark);//更新直线上被覆盖的长度
  60. }printf("%lld\n",ans);
  61. return 0;
  62. }

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. 史上最浅显易懂的Git教程2 github

    Git是分布式版本控制系统,同一个Git仓库,可以分布到不同的机器上.怎么分布呢?最早,肯定只有一台机器有一个原始版本库,此后,别的机器可以“克隆”这个原始版本库,而且每台机器的版本库其实都是一样的, ...

  2. lnmp建站常识

    1.nginx配置网站目录并修改访问的端口:nginx.conf文件 listen 666;//端口默认为80,修改后增强安全性 server_name www.lnmp.org; index ind ...

  3. 基于redis的分布式锁二种应用场景

    “分布式锁”是用来解决分布式应用中“并发冲突”的一种常用手段,实现方式一般有基于zookeeper及基于redis二种.具体到业务场景中,我们要考虑二种情况: 一.抢不到锁的请求,允许丢弃(即:忽略) ...

  4. python 基础 3.1 打开文件 a a+ r+ w+ 详解

      一.python 访问文件   1.在python中要访问文件,首先要打开文件,也就是open ---open   r:  只读   w:  只写 ,文件已存在则清空,不存在则创建   a:追加 ...

  5. String代码示例

    package lianxi; public class lianxi0112 { public static void main(String[] args) { // TODO 自动生成的方法存根 ...

  6. linq to xml操作XML(转)

    转自:http://www.cnblogs.com/yukaizhao/archive/2011/07/21/linq-to-xml.html LINQ to XML提供了更方便的读写xml方式.前几 ...

  7. 注册HttpHandler

    How to: Register HTTP Handlers After you have created a custom HTTP handler class, you must register ...

  8. python的接口类的思考?

    1.java怎么实现多继承的功效:https://www.cnblogs.com/Berryxiong/p/6142735.html 2.python的接口类和抽象类:https://www.cnbl ...

  9. 九度OJ 1010:A + B (字符串处理)

    时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:7166 解决:3646 题目描述: 读入两个小于100的正整数A和B,计算A+B. 需要注意的是:A和B的每一位数字由对应的英文单词给出. ...

  10. 认识影片版本(CAM、TS、TC、DVD、HD、BD、TVRIP等)

    许多朋友在下载电影的时候, 往往会被各种各样的版本标识弄糊涂,今天把各种版本的缩写收集在一起,希望对大家有所帮助 . 引用: 1.CAM(枪版)    CAM 通常是用数码摄像机从电影院盗录.有时会使 ...