对于横轴,加上与上一次扫描的差值;对于竖轴,加上高度差与区间内不相交线段\(*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 (线段树扫描线)的更多相关文章

  1. luogu1856 [USACO5.5]矩形周长Picture

    看到一坨矩形就要想到扫描线.(poj atantis) 我们把横边竖边分开计算,因为横边竖边其实没有区别,以下论述全为考虑竖边的. 怎样统计一个竖边对答案的贡献呢?答:把这个竖边加入线段树,当前的总覆 ...

  2. P1856 [USACO5.5]矩形周长Picture

    P1856 [USACO5.5]矩形周长Picture $len$            $sum$              $num$             $flag\_l$ $flage\_ ...

  3. hdu1828 Picture(线段树+扫描线+矩形周长)

    看这篇博客前可以看一下扫描线求面积:线段树扫描线(一.Atlantis HDU - 1542(覆盖面积) 二.覆盖的面积 HDU - 1255(重叠两次的面积))  解法一·:两次扫描线 如图我们可以 ...

  4. Luogu P1856 [USACO5.5]矩形周长Picture

    线段树+扫描线 经典的扫描线问题 首先将一个矩形看作由竖着的两条边和横着的两条边构成 那分成两次考虑,一次考虑竖边,一次考虑横边 首先考虑横边 如图两个矩形,现将横边擦去,留下竖边,将平面划分成3个区 ...

  5. luogu P1856 [USACO5.5]矩形周长Picture 扫描线 + 线段树

    Code: #include<bits/stdc++.h> #define maxn 200007 #define inf 100005 using namespace std; void ...

  6. 洛谷P1856 [USACO5.5]矩形周长Picture

    题目背景 墙上贴着许多形状相同的海报.照片.它们的边都是水平和垂直的.每个矩形图片可能部分或全部的覆盖了其他图片.所有矩形合并后的边长称为周长. 题目描述 编写一个程序计算周长. 如图1所示7个矩形. ...

  7. POJ 1177 Picture(线段树 扫描线 离散化 求矩形并面积)

    题目原网址:http://poj.org/problem?id=1177 题目中文翻译: 解题思路: 总体思路: 1.沿X轴离散化建树 2.按Y值从小到大排序平行与X轴的边,然后顺序处理 如果遇到矩形 ...

  8. P1856 [USACO5.5]矩形周长Picture[扫描线]

    题目背景 墙上贴着许多形状相同的海报.照片.它们的边都是水平和垂直的.每个矩形图片可能部分或全部的覆盖了其他图片.所有矩形合并后的边长称为周长. 题目描述 编写一个程序计算周长. 如图1所示7个矩形. ...

  9. HDU1255 覆盖的面积 —— 求矩形交面积 线段树 + 扫描线 + 离散化

    题目链接:https://vjudge.net/problem/HDU-1255 给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积. Input输入数据的第一行是一个正整数T(1<= ...

随机推荐

  1. docker服务部署、迁移与备份、dockerfile、私有仓库

    今日内容概要 服务部署 迁移与备份 dockerfile 私有仓库 内容详细 1.服务部署 # 装 mysql redis --->源码编译安装-->启 动 # 有了docker后,容器操 ...

  2. Kubernetes client-go 源码分析 - ListWatcher

    概述ListWatch 对象的创建GetterListWatchList() & Watch() 概述 源码版本信息 Project: kubernetes Branch: master La ...

  3. 图解MySQL逻辑备份的实现流程

    1. 摘要 数据作为一家公司的重要资产,其重要程度不言而喻.数据库为数据提供存取服务,担任着重要的角色,如果因数据误删.服务器故障.病毒入侵等原因导致数据丢失或服务不可用,会对公司造成重大损失,所以数 ...

  4. C语言- 基础数据结构和算法 - 队列的顺序存储

    听黑马程序员教程<基础数据结构和算法 (C版本)>, 照着老师所讲抄的, 视频地址https://www.bilibili.com/video/BV1vE411f7Jh?p=1 喜欢的朋友 ...

  5. 一些好用的javascript/typescript方法封装分享

    1.数字格式化 JS版-直接写到原型链上 /** * @author: silencetea * @name: * @description: 数字格式化,默认每三位用英文逗号分隔 * @param ...

  6. mysql5.7安装要踩的坑

    因为官网下载的是绿色版,所以要做一些配置 1.在mysql根目录新增data文件夹和my.ini文件 my.ini文件内容 [mysql]# 设置mysql客户端默认字符集default-charac ...

  7. ShardingSphere-proxy-5.0.0分布式雪花ID生成(三)

    一.目的 保证在分库分表中每条数据具有唯一性 二.修改配置文件config-sharding.yaml,并重启服务 # # Licensed to the Apache Software Founda ...

  8. git stash 的一次惊心动魄的误删操作

    git stash 的一次惊心动魄的误删操作 简介:行走在互联网最低端的小熊 问题--源起: 小熊和所有混迹在互联网中的开发一样,公司里面用git来管理项目,由于可能经常有几个问题要开发,要频繁在多分 ...

  9. .NET6接入Skywalking链路追踪完整流程

    一.Skywalking介绍 Skywalking是一款分布式链路追踪组件,什么是链路追踪? 随着微服务架构的流行,服务按照不同的维度进行拆分,一次请求往往需要涉及到多个服务.互联网应用构建在不同的软 ...

  10. docker 映射端口穿透内置防火墙

    一.问题现象 1.现象举例: # 自制的springboot项目的dockerfile # springboot 其实就是一个简单的hello-world程序,写了一个HelloController ...