Luogu1856 [USACO5.5]矩形周长Picture (线段树扫描线)
对于横轴,加上与上一次扫描的差值;对于竖轴,加上高度差与区间内不相交线段\(*2\)的积;
难点在pushdown,注意维护覆盖关系。再就注意负数
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#define R(a,b,c) for(register int a = (b); a <= (c); ++ a)
#define nR(a,b,c) for(register int a = (b); a >= (c); -- a)
#define Max(a,b) ((a) > (b) ? (a) : (b))
#define Min(a,b) ((a) < (b) ? (a) : (b))
#define Fill(a,b) memset(a, b, sizeof(a))
#define Abs(a) ((a) < 0 ? -(a) : (a))
#define Swap(a,b) a^=b^=a^=b
#define ll long long
#define ON_DEBUG
#ifdef ON_DEBUG
#define D_e_Line printf("\n\n----------\n\n")
#define D_e(x) cout << #x << " = " << x << endl
#define Pause() system("pause")
#else
#define D_e_Line ;
#endif
struct ios{
template<typename ATP>ios& operator >> (ATP &x){
x = 0; int f = 1; char c;
for(c = getchar(); c < '0' || c > '9'; c = getchar()) if(c == '-') f = -1;
while(c >= '0' && c <= '9') x = x * 10 + (c ^ '0'), c = getchar();
x*= f;
return *this;
}
}io;
using namespace std;
#define lson rt << 1, l, mid
#define rson rt << 1 | 1, mid + 1, r
const int N = 20007;
struct Line{
int l, r, h, tag;
bool operator < (const Line &com)const{
if(h != com.h) return h < com.h;
return tag > com.tag;
}
}a[N];
struct Tree{
int sum, num, len, ltag, rtag;
}t[N << 2];
inline void Pushdown(int rt, int l, int r){
if(t[rt].sum){
t[rt].num = 1;
t[rt].len = r - l + 1;
t[rt].ltag = t[rt].rtag = 1;
return;
}
if(l == r){
t[rt].len = 0;
t[rt].num = 0;
t[rt].ltag = t[rt].rtag = 0;
return;
}
t[rt].len = t[rt << 1].len + t[rt << 1 | 1].len;
t[rt].num = t[rt << 1].num + t[rt << 1 | 1].num;
if(t[rt << 1].rtag && t[rt << 1 | 1].ltag) --t[rt].num;
t[rt].ltag = t[rt << 1].ltag;
t[rt].rtag = t[rt << 1 | 1].rtag;
}
inline void Updata(int rt, int l, int r, int L, int R, int w){
if(L <= l && r <= R){
t[rt].sum += w;
Pushdown(rt, l, r);
return;
}
int mid = (l + r) >> 1;
if(L <= mid) Updata(lson, L, R, w);
if(R > mid) Updata(rson, L, R, w);
Pushdown(rt, l, r);
}
int main(){
int n, m = 0;
io >> n;
int maxx = 0xcfcfcfcf, minn = 0x7fffffff;
R(i,1,n){
int X1, Y1, X2, Y2;
io >> X1 >> Y1 >> X2 >> Y2;
maxx = Max(maxx, X2);
minn = Min(minn, X1);
a[++m] = (Line){X1, X2, Y1, 1};
a[++m] = (Line){X1, X2, Y2, -1};
}
if(minn <= 0){
R(i,1,m){
a[i].l -= minn - 1;
a[i].r -= minn - 1;
}
maxx -= minn - 1;
}
sort(a + 1, a + m + 1);
int ans = 0, last = 0;
R(i,1,m){
Updata(1, 1, maxx, a[i].l, a[i].r - 1, a[i].tag);
while(a[i].h == a[i + 1].h && a[i].tag == a[i + 1].tag){
++i;
Updata(1, 1, maxx, a[i].l, a[i].r - 1, a[i].tag);
}
ans += Abs(t[1].len - last) + (t[1].num * (a[i + 1].h - a[i].h) << 1);
last = t[1].len;
}
printf("%d\n",ans);
return 0;
}

Luogu1856 [USACO5.5]矩形周长Picture (线段树扫描线)的更多相关文章
- luogu1856 [USACO5.5]矩形周长Picture
看到一坨矩形就要想到扫描线.(poj atantis) 我们把横边竖边分开计算,因为横边竖边其实没有区别,以下论述全为考虑竖边的. 怎样统计一个竖边对答案的贡献呢?答:把这个竖边加入线段树,当前的总覆 ...
- P1856 [USACO5.5]矩形周长Picture
P1856 [USACO5.5]矩形周长Picture $len$ $sum$ $num$ $flag\_l$ $flage\_ ...
- hdu1828 Picture(线段树+扫描线+矩形周长)
看这篇博客前可以看一下扫描线求面积:线段树扫描线(一.Atlantis HDU - 1542(覆盖面积) 二.覆盖的面积 HDU - 1255(重叠两次的面积)) 解法一·:两次扫描线 如图我们可以 ...
- Luogu P1856 [USACO5.5]矩形周长Picture
线段树+扫描线 经典的扫描线问题 首先将一个矩形看作由竖着的两条边和横着的两条边构成 那分成两次考虑,一次考虑竖边,一次考虑横边 首先考虑横边 如图两个矩形,现将横边擦去,留下竖边,将平面划分成3个区 ...
- luogu P1856 [USACO5.5]矩形周长Picture 扫描线 + 线段树
Code: #include<bits/stdc++.h> #define maxn 200007 #define inf 100005 using namespace std; void ...
- 洛谷P1856 [USACO5.5]矩形周长Picture
题目背景 墙上贴着许多形状相同的海报.照片.它们的边都是水平和垂直的.每个矩形图片可能部分或全部的覆盖了其他图片.所有矩形合并后的边长称为周长. 题目描述 编写一个程序计算周长. 如图1所示7个矩形. ...
- POJ 1177 Picture(线段树 扫描线 离散化 求矩形并面积)
题目原网址:http://poj.org/problem?id=1177 题目中文翻译: 解题思路: 总体思路: 1.沿X轴离散化建树 2.按Y值从小到大排序平行与X轴的边,然后顺序处理 如果遇到矩形 ...
- P1856 [USACO5.5]矩形周长Picture[扫描线]
题目背景 墙上贴着许多形状相同的海报.照片.它们的边都是水平和垂直的.每个矩形图片可能部分或全部的覆盖了其他图片.所有矩形合并后的边长称为周长. 题目描述 编写一个程序计算周长. 如图1所示7个矩形. ...
- HDU1255 覆盖的面积 —— 求矩形交面积 线段树 + 扫描线 + 离散化
题目链接:https://vjudge.net/problem/HDU-1255 给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积. Input输入数据的第一行是一个正整数T(1<= ...
随机推荐
- 关于我学git这档子事(2)
将本地main分支push到远程dev分支(不同名分支间的push) 远程dev分支还未创建 (在push同时创建远程dev分支,并将本地main分支内容上传) git push -u --set-u ...
- PostgreSQL 的窗口函数 OVER, WINDOW, PARTITION BY, RANGE
最近在数据处理中用到了窗函数, 把使用方法记录一下, 暂时只有分组排序和滑动时间窗口的例子, 以后再逐步添加 场景 在SQL查询时, 会遇到有两类需要分组统计的场景, 在之前的SQL语法中是不方便实现 ...
- CF1485E Move and Swap
题意:Move and Swap 很好的题呢 n个节点的树,根为1,所有叶子的深度都是D,一开始根节点上有两个颜色分别微R,B的球,你执行下列操作D-1次: 1.R点跳到子树内 2.B点跳到下一层的任 ...
- 【原创】项目五w1r3s.v1.0
实战记录 1.nmap信息枚举 1)C段扫描 nmap -sP 192.168.186.0/24 2)扫描全端口信息 nmap -p- 192.168.186.143 3)扫描版本信息 nmap -p ...
- CentOS7及以下版本安装禅道
由于是CentOS7以及以下系统,禅道已经集成了 Apache Nginx Mysql 服务,不需要我们再次安装搭建,我们只进行解压使用就好: 一.进行下载安装 1.在终端命令中输入以下命令确认系统是 ...
- 一文澄清网上对 ConcurrentHashMap 的一个流传甚广的误解!
大家好,我是坤哥 上周我在极客时间某个课程看到某个讲师在讨论 ConcurrentHashMap(以下简称 CHM)是强一致性还是弱一致性时,提到这么一段话 这个解释网上也是流传甚广,那么到底对不对呢 ...
- Linux/Ubuntu 安装Redis
更新记录 2022年6月15日 发布. 2022年6月12日 开始编写. 安装Redis 更新源 sudo apt update 安装redis sudo apt install redis-serv ...
- 『忘了再学』Shell流程控制 — 33、if条件判断语句(一)
目录 1.单分支if条件语句 2.双分支if条件语句 (1)示例1 (2)示例2 什么是流程控制? 普通理解:Shell编写的程序是顺序执行的,也就是说第一命令先执行,然后接着执行第二条命令,然后再下 ...
- flink窗口分类
窗口分类 按照驱动类型分类 窗口本身是截取有界数据的一种方式,所以窗口一个非常重要的信息就是"怎样截取数据".换句话说,就是以什么标准来开发和结束数据的截取. 按照驱动类型分类主要 ...
- go-zero微服务实战系列(五、缓存代码怎么写)
缓存是高并发服务的基础,毫不夸张的说没有缓存高并发服务就无从谈起.本项目缓存使用Redis,Redis是目前主流的缓存数据库,支持丰富的数据类型,其中集合类型的底层主要依赖:整数数组.双向链表.哈希表 ...