求\(n\)个矩形的面积并,可以用线段树维护一条垂直于\(y\)轴的直线上被矩形覆盖的长度有多少长,将直线从左往右扫一遍,遇到矩形左边界就+1,遇到右边界就-1,不为\(0\)的位置就表示没有覆盖

不为\(0\)的位置的多少似乎不好维护,

考虑这样一个性质:

如果一个线段树上的区间在扫过一个矩形的左边界被全部覆盖,那么在这个扫过矩形的右边界之前它都是全部被覆盖着的,并且我们每次询问都是询问[1,n]

我们可以在线段树上记录一个\(cnt\)表示一个区间被几个矩形完全覆盖了,如果cnt!=0,那么这个区间的\(ans=r-l\),这样就不需要标记下传了

如果cnt==0,那么用左儿子的ans加上右儿子的ans就可以了

注意线段树左右合并时中间的长度没有计算,所以要用[l,r]的线段树结点维护[l,r+1]的区间

因为数据范围较大,需要离散化

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<map>
#define lc p<<1
#define rc p<<1|1
#define mid ((l+r)>>1)
using namespace std; const int MAXN=100010; inline int read(){
int x=0; char c=getchar();
while(c<'0') c=getchar();
while(c>='0') x=x*10+c-'0',c=getchar();
return x;
} struct Matrix{
int x1_,x2_,y1_,y2_;
} a[MAXN]; int n,xx[MAXN<<1],cnt;
int revx[MAXN<<1]; long long Ans; map<int,int> mx; struct Upd{
int yid,l,r,k;
} u[MAXN<<1]; inline bool cmp(Upd p,Upd q){
return p.yid<q.yid;
} int len[MAXN<<4],Cnt[MAXN<<4],numx; inline void push_up(int p,int l,int r){
if(Cnt[p]){
len[p]=revx[r+1]-revx[l];
if(l!=r)
cout<<len[p]<<' '<<len[lc]+len[rc]<<' '<<Cnt[lc]<<' '<<Cnt[rc]<<endl;
}
else len[p]=len[lc]+len[rc];
} inline void update(int L,int R,int d,int p=1,int l=1,int r=numx){
if(L<=l&&r<=R){
Cnt[p]+=d;
push_up(p,l,r);
return;
}
if(L<=mid) update(L,R,d,lc,l,mid);
if(R>mid) update(L,R,d,rc,mid+1,r);
push_up(p,l,r);
} signed main()
{
n=read();
for(int i=1;i<=n;++i){
a[i].x1_=read(),a[i].y1_=read();
a[i].x2_=read(),a[i].y2_=read();
xx[++cnt]=a[i].x1_;
xx[++cnt]=a[i].x2_;
}
sort(xx+1,xx+1+cnt);
for(int i=1;i<=cnt;++i)
if(xx[i]!=xx[i-1])
mx[xx[i]]=++numx,revx[numx]=xx[i];
int unum=0;
for(int i=1;i<=n;++i){
u[++unum].yid=a[i].y1_;
u[unum].l=a[i].x1_;
u[unum].r=a[i].x2_;
u[unum].k=1;
u[++unum].yid=a[i].y2_;
u[unum].l=a[i].x1_;
u[unum].r=a[i].x2_;
u[unum].k=-1;
}
sort(u+1,u+1+unum,cmp);
for(int i=1;i<=unum;++i){
if(i>1&&u[i].yid!=u[i-1].yid){
Ans+=1ll*len[1]*(u[i].yid-u[i-1].yid);
}
update(mx[u[i].l],mx[u[i].r]-1,u[i].k);
}
printf("%lld\n",Ans);
return 0;
}

【luoguP5490】【模板】扫描线的更多相关文章

  1. 线段树基础模板&&扫描线

    线段树的单点更新+区间求和 hdu1166敌兵布阵 Input 第一行一个整数T,表示有T组数据. 每组数据第一行一个正整数N(N<=),表示敌人有N个工兵营地 ,接下来有N个正整数,第i个正整 ...

  2. Atitit 路径规划法attilax总结 扫描线路法

    Atitit 路径规划法attilax总结 扫描线路法 2017/2/8 20:43:37[吐槽]深圳-小 2017/2/8 20:43:37 群主做什么的2017/2/10 10:03:15系统消  ...

  3. 矩形面积并-扫描线 线段树 离散化 模板-poj1151 hdu1542

    今天刚看到这个模板我是懵逼的,这个线段树既没有建树,也没有查询,只有一个update,而且区间成段更新也没有lazy标记....研究了一下午,我突然我发现我以前根本不懂扫描线,之所以没有lazy标记, ...

  4. 覆盖的面积 HDU - 1255 (线段树-扫描线)模板提

    给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积. Input输入数据的第一行是一个正整数T(1<=T<=100),代表测试数据的数量.每个测试数据的第一行是一个正整数N(1& ...

  5. HDU 1542.Atlantis-线段树求矩形面积并(离散化、扫描线/线段树)-贴模板

    好久没写过博客了,这学期不是很有热情去写博客,写过的题也懒得写题解.现在来水一水博客,写一下若干年前的题目的题解. Atlantis Time Limit: 2000/1000 MS (Java/Ot ...

  6. LA 4127 - The Sky is the Limit (离散化 扫描线 几何模板)

    题目链接 非原创 原创地址:http://blog.csdn.net/jingqi814/article/details/26117241 题意:输入n座山的信息(山的横坐标,高度,山底宽度),计算他 ...

  7. HDU1828 Picture 线段树+扫描线模板题

    Picture Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Sub ...

  8. [P5490] 【模板】扫描线 - 线段树

    求 \(n\) 个矩形的面积并 Solution 将矩形转化为 \(y_1\) 位置的 + 修改 和 \(y_2\) 位置的 - 修改.然后按照 \(+y\) 顺序依次处理所有的修改,到达的一个新的位 ...

  9. HDU 1542 线段树+扫描线+离散化

    Atlantis Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Su ...

随机推荐

  1. 史上最全HashMap红黑树解析

    HashMap红黑树解析 红黑树介绍 TreeNode结构 树化的过程 红黑树的左旋和右旋 TreeNode的左旋和右旋 红黑树的插入 TreeNode的插入 红黑树的删除 TreeNode的删除节点 ...

  2. 在Unity 5中优化SkinnedMeshRenderer

    过早优化是万恶之源”——Donald Knuth        不少开发者在前期开发过程中对算法等类似的开销都甚少关心,而是更倾向于尽可能简单的解决某个问题,后面必要时再进行优化.这能极大加速开发进度 ...

  3. 18 java I/O 系统

    流的类继承结构 我们首先看看流的类继承结构,有助于理解下个标签的内容 InputStream OutputStream Reader Writer File类 File类技能表示一个特定文件的名称,又 ...

  4. AppTheme属性设置集合

    现在新建一个项目基本都会在 style.xml 设置基础的 AppTheme,但是系统的给提供的设置属性又比较多. 所以在此收集记录,以便之后查找方便. <style name="Ap ...

  5. 原油PETROLAEUM英语PETROLAEUM石油

    petrolaeum (uncountable) Archaic spelling of petroleum petroleum See also: Petroleum Contents [hide] ...

  6. android studio打印

    写入打印语句 System.out.println("hello furong"); 添加打印过滤 指定过滤规则 Filter Name:随便写 Log Tag:日志标志 Log ...

  7. Servlet , GenericServlet和HttpServlet

    Servlet是一套规范,表现为一套接口,留给开发人员去实现,Servlet接口定义如下(附加servlet-api source来查看源码) 其中init方法被Servlet容器调用,servlet ...

  8. idea导入mybatis源码

    1.最近在学mybatis,想下载源码导入idea结果网上一查没有一篇完整的,结果让我进了个大坑,算了,废话少说 2.两种办法,一个是git客户端克隆,另外一个是下载code压缩包.先说通过git客户 ...

  9. mysql 外键的基本使用

    外键的使用条件: 两个表必须是InnoDB表,MyISAM表暂时不支持外键外键列必须建立了索引,MySQL 4.1.2以后的版本在建立外键时会自动创建索引,但如果在较早的版本则需要显式建立:外键关系的 ...

  10. 随笔记录--Array类型

    前言:除了Object类型之外,Array类型恐怕是ECMAScript中最常用的类型了.而且,ECMAScript中数组与其他多数语言中的数组有很大差别,ECMAScript数组中的每一项可以保存任 ...