火星探险 (Mars)

2023-11-16

暂无链接

题目描述

在2051年,若干火星探险队探索了这颗红色行星的不同区域并且制作了这些区域的地图。现在,Baltic空间机构有一个雄心勃勃的计划,他们想制作一张整个行星的地图。为了考虑必要的工作,他们需要知道地图上已经存在的全部区域的大小。你的任务是写一个计算这个区域大小的程序。

具体任务要求为:

(1)从输入中读取地图形状的描述;

(2)计算地图覆盖的全部的区域;

(3)输出探索区域的总面积(即所有矩形的公共面积)。

输入格式

输入的第一行包含一个整数n 1n10000 ( 1 ≤ n ≤ 10000 ) ,表示可得到的地图数目。

以下n行,每行描述一张地图。每行包含4个整数x1,y1,x2和y2( 0x1x230000 0 ≤ x 1 < x 2 ≤ 30000 , 0y1y230000 0 ≤ y 1 < y 2 ≤ 30000 )。数值 x1,y1 ( x 1 , y 1 ) x2y2 ( x 2 , y 2 ) 是坐标,分别表示绘制区域的左下角和右上角坐标。每张地图是矩形的,并且它的边是平行于x坐标轴或y坐标轴的。

输出格式

输出文件包含一个整数,表示探索区域的总面积(即所有矩形的公共面积)。

输入样例

2
10 10 20 20
15 15 25 30

输出样例

225

解题分析:

赤裸裸的扫描线…和 窗口的星星 的思路一样, 将x坐标离散化, 将上下底按y轴坐标排序, 用线段树维护当前存在的矩形下底。

我们可以将下底权值设为1,上底权值设为-1, 每次更新线段树区间后将面积加上当前可用的下底乘上与下一条底边间高度的差。

关键在于如何维护底的长度。 我们可以在线段树中维护一个值 len l e n 表示当前区间可用的总长度, 以及另一个值 valid v a l i d 表示当前区间是否可用。我们每次更新(加入一条新的边)时就更新根据valid值更新。有三种情况:

1. valid!=0 v a l i d ! = 0 :说明当前区间可用, 所以当前区域的可用底边长度即为 xrightxleft1 x r i g h t − x l e f t − 1

2. valid=0 v a l i d = 0 lef=rig l e f = r i g :说明当前点已没有线段覆盖,可用长度为0。

3.其他情况:即 lef!=rig l e f ! = r i g valid=0 v a l i d = 0 , 说明之前可能有modify到更小子区域的情况,(在这里valid并不是向上传导的), 所以当前区域的可用底边长度为 len(sonleft)+len(sonright) l e n ( s o n l e f t ) + l e n ( s o n r i g h t ) 。这个性质的前提是:因为每条下底都有对应的上底, 所以当上底加入时区间中还有可能有可用的区间底边,且不会与抵消了的下底重复, 因为加入下底的时候并没有将 len l e n 下传到下一层的点, 下一层的len只可能是其他边赋上的。

下面上代码:

#include <cstdio>
#include <cctype>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#define R register
#define gc getchar()
#define W while
#define IN inline
#define MX 50005
#define db double
template <typename T>
IN void in(T &x)
{
    x = 0; R char c = gc;
    W (!isdigit(c)) c = gc;
    W (isdigit(c))
    {x = (x << 1) + (x << 3), x += c - 48, c = gc;}
}
namespace SGT
{
    #define ls now << 1
    #define rs now << 1 | 1
    int x[MX], left[MX], right[MX];
    int num, tot, cnt;
    struct Edge
    {
        int x, y, id, typ;
    }data[MX << 1], anti[MX << 1];
    IN bool cmp_x (const Edge &x, const Edge &y)
    {return x.x < y.x;}
    IN bool cmp_y (const Edge &x, const Edge &y)
    {return x.y == y.y ? x.typ > y.typ : x.y < y.y;}
    //在这里和窗口的星星一题不同的是, 其实不必将负值的边排在前面,因为有多条边的时候它们之间的高为0
    IN bool operator == (const Edge &x, const Edge &y)
    {
        return x.x == y.x;
    }
    struct Node
    {
        int valid, lef, rig, len; 
    }tree[MX << 1];
    void build(int now, int l, int r)
    {
        tree[now].lef = l, tree[now].rig = r;
        if(l == r) return;
        int mid = (l + r) >> 1;
        build(ls, l, mid);
        build(rs, mid + 1, r);
    }
    IN void pushup(const int &now)
    {
        if(tree[now].valid) tree[now].len = x[tree[now].rig ] - x[tree[now].lef - 1];
        //因为保存的为点, 为了不少加区间之间的那部分,左端点需要减一
        else if(tree[now].lef == tree[now].rig) tree[now].len = 0; 
        else tree[now].len = tree[ls].len + tree[rs].len;
    }
    void modify(const int &now, const int &lb, const int &rb, const int &delta)
    {
        if(tree[now].lef == lb && tree[now].rig == rb)
        {
            tree[now].valid += delta;
            pushup(now);
            return;
        }
        int mid = (tree[now].lef + tree[now].rig) >> 1;
        if(mid >= rb) modify(ls, lb, rb, delta);
        else if(mid < lb) modify(rs, lb, rb, delta);
        else
        {
            modify(ls, lb, mid, delta);
            modify(rs, mid + 1, rb, delta);
        }
        pushup(now);
    }
}
using namespace SGT;
using std::sort;
using std::unique;
int main()
{
    int lf, dn, rg, up;
    in(num);
    for (R int i = 1; i <= num; ++i)
    {
        in(lf), in(dn), in(rg), in(up);
        data[++tot].x = lf, data[tot].id = i, data[tot].typ = 0;
        anti[tot].y = dn, anti[tot].id = i, anti[tot].typ = 0;
        data[++tot].x = rg, data[tot].id = i, data[tot].typ = 1;
        anti[tot].y = up, anti[tot].id = i, anti[tot].typ = 1;
    }
    sort(data + 1, data + 1 + tot, cmp_x);
    sort(anti + 1, anti + 1 + tot, cmp_y);
    for (R int i = 1; i <= tot; ++i)
    {//离散化
        if(i == 1 || data[i].x != data[i - 1].x) ++cnt;
        x[cnt] = data[i].x;
        if(!data[i].typ) left[data[i].id] = cnt;
        else right[data[i].id] = cnt;
    }
    build(1, 1, cnt);
    int ans = 0;
    for (R int i = 1; i < tot; ++i)
    {
        if(!anti[i].typ)
        modify(1, left[anti[i].id] + 1, right[anti[i].id], 1);
        else//因为modify的时候lef减了一,所以这里要加上
        modify(1, left[anti[i].id] + 1, right[anti[i].id], -1);
        ans += (anti[i + 1].y - anti[i].y) * tree[1].len;
    }
    printf("%d", ans);
    return 0;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

火星探险 (Mars) 的相关文章

  • Codeforces Round #291 (Div. 2)

    题目链接contest 514 A Chewba ca and Number 不允许有前导零 所以如果第一位是9的话 需要特别考虑 一开始理解错了题意 又WA了呜呜呜 include
  • Mosaic 【HDU - 4819】【二维线段树】

    题目链接 这道题难就只是难在题目难读 题意读懂后就是一道普通的二维线段树更新查找问题 题意 给你一个N N的矩阵 并且已经建立了初始值 然后给你个点以及L 很多人不解其义 其实就是给你个点 然后查的是以 x y 为基础的点 在以左上角 x
  • 爱线段树的好孩子【九校2D1T3】优美序列

    Lxy养了N头奶牛 他把N头奶牛用1 N编号 第i头奶牛编号为i 为了让奶牛多产奶 每天早上他都会让奶牛们排成一排做早操 奶牛们是随机排列的 在奶牛排列中 如果一段区间 L R 中的数从小到大排列后是连续的 他认为这段区间是优美的 比如奶牛
  • A Magic Lamp 【HDU - 3183】【线段树区间最小值】

    题目链接 简单而言 这道题就是RMQ问题 但是我个人更喜欢用线段树来写区间最大值 因为这样子会好更新些 奈何这道题不需要更新 我们要从长度为N的字符串中删除M个元素 那么岂不是只剩下 N M 个字符串的长度 所以 我们不妨来找 N M 的长
  • 关于叉积

    学过计算几何以后 我发现几乎每一道题都用到了叉积这个东西 叉积是什么呢 在这个图中 以原点为中心 叉积就是x1 y2 x2 y1 记得话就记1221 x前y后 但是这并不是完全正确 比如说这个图 在这个图中 点1和点2是以点0为中心 不是原
  • Rikka with Phi 【HDU - 5634】【线段树+欧拉函数】

    题目链接 很好的一道题 也算是开阔了我的思维 一开始 我的想法是既然是区间求欧拉 那么到一定地步的时候 数的欧拉值就会降到1 那我们维护区间值等于区间长度不就是可以了吗 然后T了 然后我再想 是不是哪里可以优化 毕竟还有另外一个条件没用优化
  • Atlantis 【POJ - 1151】【扫描线模板讲解】

    题目链接 是第二次写这道题了 但是也加深了我对扫描线的印象了 具体什么是扫描线 我们就如是讲讲吧 扫描线就是为了方便处理有重的区间面积的方式 我们通过线段树的方式去优化它 可以做到更少的时间复杂度 对于一个二维平面 我们用一个平行于Y轴的线
  • 3D扫描技术概览

    3D扫描技术概览 复制链接 楼主 eseedo 发表于 2016 11 22 17 14 26 408 0 只看该作者 内容概要 1 使
  • csu 1811 Tree Intersection 2016湖南省赛 I

    Problem acm csu edu cn csuoj problemset problem pid 1811 vjudge net contest 161962 problem I Reference blog csdn net qwb
  • 【2019年ICPC南昌网络赛】Distance on the tree【DFS+线段树合并(可持久化线段树)】

    题目链接 DSM Data Structure Master once learned about tree when he was preparing for NOIP National Olympiad in Informatics i
  • Just a Hook

    http acm hdu edu cn showproblem php pid 1698 Problem Description In the game of DotA Pudge s meat hook is actually the m
  • CGAL计算几何算法库安装和使用(一)

    CGAL是使用C 开发的计算几何算法库 提供Delaunay三角网 网格生成 多边形 以及各种几何处理算法 应用领域 计算机图形学 科学可视化 计算机辅助设计与建模 地理信息系统 分子生物学 医学影像学 机器人学和运动规划 和数值方法 1
  • poj 2155 Matrix

    Problem poj org problem id 2155 vjudge net contest 146952 problem A Meaning 一个 N N 的矩阵 A 初始时全部值为 0 有两种操作 1 C x1 y1 x2 y2
  • Kattis Doors

    Problem open kattis com problems doors vjudge net contest 183886 problem B Reference 点到线段的最短距离算法 Meaning 有两个球 Alex 和 Bob
  • CGAL例程:地理信息系统----点云数据生成DSM、DTM、等高线和数据分类

    作者 西蒙 吉罗多 链接 CGAL 5 4 Manual GIS Geographic Information System 目录 1 概述 2 不规则三角形网数据表示 TIN 3 数字表面模型表示 DSM 4 数字地形模型表示 DTM 4
  • 【SSL_1232】雷达覆盖

    思路 以一个点作为平角 计算几何统计 c o d e code code include
  • 线段树(java)

    线段树描述 线段树是一种二叉搜索树 与区间树相似 它将一个区间划分成一些单元区间 每个单元区间对应线段树中的一个叶结点 使用线段树可以快速的查找某一个节点在若干条线段中出现的次数 时间复杂度为O logN 而未优化的空间复杂度为2N 实际应
  • 2021CCPC河南省赛题解(主席树+二分)

    考场没看见随机化数据 写了一个主席树 二分 但是之前练习的时候没有做过多实例 忘记初始化上层用到的所有节点信息了 wa麻了 思路 主席树 二分 O nlogn 2 二分距离当前点最近的 大于等于a i 的数的个数最靠右的位置 然后利用主席树
  • The centre of polygon (多边形重心)

    描述 Given a polygon your task is to find the centre of gravity for the given polygon 输入 The input consists of T test case
  • Matrix 【POJ - 2155】【二维线段树+永久化标记】

    题目链接 挺好的一道题 一开始用lazy标记往下推 总是推不出样例的正解 然后就去看了相关博客 发现却确实如此 在这里是无法用lazy标记来层层推的 并且还会出现超内存的情况 所以 便改用了永久化标记来解这道题 还有一件是 关于discus

随机推荐

  • 数据库中表数据备份

    目的 在所有的数据仓库类项目中几乎都会涉及到数据库中表数据备份的操作 主要是为了对一些结果数据进行备份 防止误操作 过程 一 背景 本次我们用的方法是通过在数据库中建立一个备份用户进行数据备份的操作 原因是现在的数据库一般是基于HDFS开发
  • 【html】【一个简单的用户登录页面代码】

    结果 代码
  • OpenCV python 轮廓(连通域)最小外接圆形

    OpenCV python 轮廓 连通域 最小外接圆形 原图 cc jpg import cv2 import numpy as np def main 1 导入图片 img src cv2 imread cc jpg 2 灰度化 二值化
  • ndk编译

    使用方法 直接到jni目录下 和androd mk文件放在一起 ndk build j8 B cp rf libs videolibtest libs 默认编译的是 armeabi 架构的 如果有或创建Application mk文件 则在
  • 微信小程序阻止用户返回上一页,并弹窗给用户确定是否要返回上一页

    在onload中调用微信的enableAlertBeforeUnload方法 在首次进入会自动监听当前的页面 在返回的时候会自动弹出弹窗阻止用户返回上一页 点击确定则返回上一页 取消则停留在当前页 onLoad function wx en
  • 3、Linux权限管理

    3 Linux权限管理 文章目录 3 Linux权限管理 3 1 Linux chgrp命令 修改文件和目录的所属组 3 2 Linux chown命令 修改文件和目录的所有者和所属组 3 3 Linux 权限位 3 4 Linux chm
  • 删除数据库的sql语句

    删除数据库的sql语句如何写 drop database 数据库名 删除数据库的 drop table 表名 删除表的 delete from 表名 where 条件 删除数据的 truncate table 表名 也是删除数据库的 但是他
  • Qt—事件的处理

    事件的处理 一个事件由一个特定的QEvent子 类来表示 但是有时一个事件又包含多个事件类型 比如鼠标事件又可以分为鼠标按下 双击和移动等多种操作 这些事件类型都由QEvent类的枚举型QEvent Type来表示 其中包含了一百多种事件类
  • librdkafka的使用和介绍

    librdkafka的使用介绍 librdkafka是kafka的c语言接口 下面简单的介绍一下其接口 1 rd kafka conf set设置全局配置 2 rd kafka topic conf set设置topic配置 3 rd ka
  • MySQL IP地址存储和转换

    存储 保存IP地址到数据库 建议使用整型 首先可以节省存储空间 例如保存IP地址 255 255 255 255 如果使用字符串形式的IP 那么需要VARCHAR 15 来存放 而使用整型的话 用二进制是111111111111111111
  • Oulipo

    点击打开链接 Problem Description The French author Georges Perec 1936 1982 once wrote a book La disparition without the letter
  • anaconda虚拟环境python升级_Anaconda的安装与虚拟环境建立

    电脑配置 Windows10 64位操作系统 一 Anaconda的介绍 Anaconda指的是一个开源的Python发行版本 其包含了conda Python等180多个科学包及其依赖项 因为包含了大量的科学包 Anaconda 的下载文
  • 【LTspice】006 实际电容 阻抗特性曲线

    目录 1 电路图 2 仿真条件 3 电容元件选型 及 寄生参数 4 仿真结果分析 1 电路图 我们可以利用仿真软件的AC分析功能绘制电容的阻抗特性曲线 如下 放置一电容和电压源 设置如下图所示 2 仿真条件 AC 1 电压源指定小信号交流分
  • mysql日期相减操作

    一 MySQL中两个DateTime字段相减 假定表名为tblName 两个DateTime字段名分别为beginDateTime endDateTime 以下是相关两个mysql日期字段相减的SQL语句 这种方式两字段跨天 月 年都无问题
  • Android Studio教程从入门到精通

    转自 http blog csdn net yanbober article details 45306483 目标 Android Studio新手 gt 下载安装配置 gt 零基础入门 gt 基本使用 gt 调试技能 gt 构建项目基础
  • Journal of Proteome Research

    文献名 Lipidomics reveals similar changes in serum phospholipid signatures of overweight and obese paediatric subjects 用脂质组
  • pytorch1.13安装

    pytorch1 13安装 个人参考 情况交代 安装流程 注意事项 显卡配置查看 创建环境 激活环境 安装对应的torch版本 检查 使用pip list 导入查看 卸载 下载gpu版本的 验证 把这个内核加到jupyter 完成 情况交代
  • 挂载mount问题“wrong fs type, bad option, bad superblock on ”的解决办法

    重装系统后挂载一般会出现如下问题 problem ivy ivy OptiPlex 380 source sudo mount 192 168 9 18 home deep dev env source mount wrong fs typ
  • makefile进阶

    一 微观的C C 编译执行过程 c文件怎么变成可执行文件 exe 1 预处理 E 宏替换 头文件展开 去打印 gcc E hello c o hello i 2 编译 S 把 i 文件编译成汇编代码文件 i gcc S hello i o
  • 火星探险 (Mars)

    暂无链接 题目描述 在2051年 若干火星探险队探索了这颗红色行星的不同区域并且制作了这些区域的地图 现在 Baltic空间机构有一个雄心勃勃的计划 他们想制作一张整个行星的地图 为了考虑必要的工作 他们需要知道地图上已经存在的全部区域的大