【luoguP5490】【模板】扫描线
求\(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】【模板】扫描线的更多相关文章
- 线段树基础模板&&扫描线
线段树的单点更新+区间求和 hdu1166敌兵布阵 Input 第一行一个整数T,表示有T组数据. 每组数据第一行一个正整数N(N<=),表示敌人有N个工兵营地 ,接下来有N个正整数,第i个正整 ...
- Atitit 路径规划法attilax总结 扫描线路法
Atitit 路径规划法attilax总结 扫描线路法 2017/2/8 20:43:37[吐槽]深圳-小 2017/2/8 20:43:37 群主做什么的2017/2/10 10:03:15系统消 ...
- 矩形面积并-扫描线 线段树 离散化 模板-poj1151 hdu1542
今天刚看到这个模板我是懵逼的,这个线段树既没有建树,也没有查询,只有一个update,而且区间成段更新也没有lazy标记....研究了一下午,我突然我发现我以前根本不懂扫描线,之所以没有lazy标记, ...
- 覆盖的面积 HDU - 1255 (线段树-扫描线)模板提
给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积. Input输入数据的第一行是一个正整数T(1<=T<=100),代表测试数据的数量.每个测试数据的第一行是一个正整数N(1& ...
- HDU 1542.Atlantis-线段树求矩形面积并(离散化、扫描线/线段树)-贴模板
好久没写过博客了,这学期不是很有热情去写博客,写过的题也懒得写题解.现在来水一水博客,写一下若干年前的题目的题解. Atlantis Time Limit: 2000/1000 MS (Java/Ot ...
- LA 4127 - The Sky is the Limit (离散化 扫描线 几何模板)
题目链接 非原创 原创地址:http://blog.csdn.net/jingqi814/article/details/26117241 题意:输入n座山的信息(山的横坐标,高度,山底宽度),计算他 ...
- HDU1828 Picture 线段树+扫描线模板题
Picture Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Sub ...
- [P5490] 【模板】扫描线 - 线段树
求 \(n\) 个矩形的面积并 Solution 将矩形转化为 \(y_1\) 位置的 + 修改 和 \(y_2\) 位置的 - 修改.然后按照 \(+y\) 顺序依次处理所有的修改,到达的一个新的位 ...
- HDU 1542 线段树+扫描线+离散化
Atlantis Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Su ...
随机推荐
- 整理:C#中Expression表达式的妙用
原文:整理:C#中Expression表达式的妙用 一.目的:通过示例了解C#中Expression表达式的作用,通过表达式和反射可以写出很优雅的代码和架构,也可以完成一些看似不可能完成的任务 二.示 ...
- 2019 珍岛java面试笔试题 (含面试题解析)
本人5年开发经验.18年年底开始跑路找工作,在互联网寒冬下成功拿到阿里巴巴.今日头条.珍岛等公司offer,岗位是Java后端开发,因为发展原因最终选择去了珍岛,入职一年时间了,也成为了面试官,之 ...
- 简要介绍Linux网络服务的种类
如果有人问你Linux最强大的功能是什么,你大概会回答“是网络功能”.Lmux操作系统的优势之一就是网络功能了,这包含比较稳定的系统资源分配,以及较为安全的网络防护能力,所以许多人都喜欢用它来进行网络 ...
- ReactiveObjC basic
基础-> https://www.jianshu.com/p/cd4031fbf8ff 在RAC中,万物皆信号. RAC 指的就是 RactiveCocoa ,是 Github 的一个开源框架, ...
- 渐进增强(progressive enhancement)、优雅降级(graceful degradation)
渐进增强 progressive enhancement: 针对低版本浏览器进行构建页面,保证最基本的功能,然后再针对高级浏览器进行效果.交互等改进和追加功能达到更好的用户体验. 优雅降级 grace ...
- DataPipeline数据融合重磅功能丨一对多实时分发、批量读取模式
为能更好地服务用户,DataPipeline最新版本支持: 1. 一个数据源数据同时分发(实时或定时)到多个目的地: 2. 提升Hive的使用场景: 写入Hive目的地时,支持选择任意目标表字段作为 ...
- android ListView中含有按钮事件实时更新ListView数据案例
1.布局文件Listview <?xml version="1.0" encoding="utf-8"?> <android.support. ...
- PHP简单实现异步多文件上传并使用Postman测试提交图片
虽然现在很多都是使用大平台的对象存储存放应用中的文件,但有时小项目还是可以使用以前的方式上传到和程序一起的服务器上,强调一下这里是小众需求,大众可以使用阿里云的OSS,腾讯的COS,七牛的巴拉巴拉xx ...
- 【Python】列表推导式
1. 列表推导式 list1 = [1, 3, 5, 6, 8] list2 = [x * 2 for x in list1] print(list2) # [2, 6, 10, 12, 16]
- PHP的垃圾回收机制之引用计数
1,介绍 php的垃圾回收机制(GC)是在PHP5之后出现的,而在PHP5.3版本之前使用的都是“引用计数”的方式.实现引用计数的实质就是在每个内存对象中都有一个计数器,当内存对象被变量引用时,计数器 ...