【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#读写修改设置调整UVC摄像头画面-滚动
有时,我们需要在C#代码中对摄像头的滚动进行读和写,并立即生效.如何实现呢? 建立基于SharpCamera的项目 首先,请根据之前的一篇博文 点击这里 中的说明,建立基于SharpCamera的摄像 ...
- 【3.1】学习C++之再逢const
随着学习的深入,就会发现曾经学的const还有更深入的用法,现在就对const的未总结的用法进行总结. 本文就是针对const在类中的情况进行的总结. 有时我们会遇到下面这种将类的成员变量用const ...
- Maven中 jar包冲突原理与解决办法
Maven中jar包冲突是开发过程中比较常见而又令人头疼的问题,我们需要知道 jar包冲突的原理,才能更好的去解决jar包冲突的问题.本文将从jar包冲突的原理和解决两个方面阐述Maven中jar包冲 ...
- JS案例 - 城市三级联动
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- linux开发中常用的命令及技巧(连载)
1.在内核或uboot目录下搜索相关内容/文件名时:grep "USB" * -nR find -name "*USB*" 2.查看系统中设备 cat /pr ...
- Httpd服务进阶知识-基于Apache Modele的LAMP架构之Discuz!案例
Httpd服务进阶知识-基于Apache Modele的LAMP架构之Discuz!论坛案例 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.安装依赖包及数据库 博主推荐阅读: ...
- 实战 MySQL 8.0.17 Clone Plugin(转)
背景 很神奇,5.7.17 和 8.0.17,连续两个17小版本都让人眼前一亮.前者加入了组复制(Group Replication)功能,后者加入了克隆插件(Clone Plugin)功能.今天我们 ...
- 分享一个批量修改文件编码的python脚本
分享一个自己编写的递归查找子目录,将所有cpp文件编码修改为utf-8编码格式的小脚本 #i!/usr/bin/env python3 # -*- coding:utf-8 -*- import os ...
- position 的absolute会使display变成inline-block
position:absolute和float会隐式地改变display类型,不论之前什么类型的元素(display:none除外), 只要设置了position:absolute. float中任意 ...
- 洛谷 P1330 封锁阳光大学题解
题目描述 曹是一只爱刷街的老曹,暑假期间,他每天都欢快地在阳光大学的校园里刷街.河蟹看到欢快的曹,感到不爽.河蟹决定封锁阳光大学,不让曹刷街. 阳光大学的校园是一张由N个点构成的无向图,N个点之间由M ...