火星探险 (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) 的相关文章

  • ZOJ 1610 Count the Colors

    Problem acm zju edu cn onlinejudge showProblem do problemCode 1610 Reference blog csdn net shuangde800 article details 8
  • Tree 【POJ - 3237】【树链剖分+一些特殊的处理】

    题目链接 这道题 说来还的确困扰了我一个多小时 当时就在想 我该如何处理那些边权 我将边化为点 以及点 默认权值为0 的取相反数后的处理 因为点取相反数之后还是0 会困扰到那些边的 然后 我想到了 如果这段区间的返回的值为0 那么就说明了肯
  • A Magic Lamp 【HDU - 3183】【线段树区间最小值】

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

    题目链接 超级好的一道题的说 虽然看了别人的思路才有了的的想法 我好弱啊 题目求的是覆盖两次以上的区间的面积大小 那么我们要怎么做 一样的 Covercnt gt 2 就得到答案 不 不行 因为若是我们之前放进去一个小区间 然后再放一个包含
  • hihoCoder 1582 Territorial Dispute

    Problem hihocoder com problemset problem 1582 vjudge net problem HihoCoder 1582 Reference hihocoder 1582 Territorial Dis
  • 能通过一张照片(2D)得到3D的模型吗?

    如下内容已经整理成 PDF 很好奇其实如果将人眼所看到的画面保存下来 拍照 人类是可以感知照片内的各个物体 是不是可以理解成这是一种2D到3D认知的转换 作者 知乎用户 链接 https www zhihu com question 529
  • Atlantis 【POJ - 1151】【扫描线模板讲解】

    题目链接 是第二次写这道题了 但是也加深了我对扫描线的印象了 具体什么是扫描线 我们就如是讲讲吧 扫描线就是为了方便处理有重的区间面积的方式 我们通过线段树的方式去优化它 可以做到更少的时间复杂度 对于一个二维平面 我们用一个平行于Y轴的线
  • 【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
  • 计算几何02_三次样条曲线

    一 样条 样条 Spline 函数是由舍恩伯格于1946年提出的 样条是富有弹性的细木条或有机玻璃条 它的作用相当于 万能 曲线板 早期船舶 汽车 飞机放样时用铅压铁压住样条 使其通过一系列型值点 调整压铁达到设计要求后绘制其曲线 称为样条
  • Kattis Doors

    Problem open kattis com problems doors vjudge net contest 183886 problem B Reference 点到线段的最短距离算法 Meaning 有两个球 Alex 和 Bob
  • 我的第一个半平面交(1007: [HNOI2008]水平可见直线)

    点击打开链接 Description Input 第一行为N 0 lt N lt 50000 接下来的N行输入Ai Bi Output 从小到大输出可见直线的编号 两两中间用空格隔开 Sample Input 3 1 0 1 0 0 0 S
  • 牛牛的等差数列【线段树】

    题目链接 这里的突破口在于小于等于25且大于等于3的质数连乘在1e8左右 所以 我们可以在操作上 将其看作对1e8去求模 而不是对每个都进行预处理 时间复杂度 也就是说 我们排除这个预处理之后 直接就是降了10倍左右的复杂度 然后 给区间一
  • 敌兵布阵

    http acm hdu edu cn showproblem php pid 1166 Problem Description C国的死对头A国这段时间正在进行军事演习 所以C国间谍头子Derek和他手下Tidy又开始忙乎了 A国在海岸线
  • 【SSL_1232】雷达覆盖

    思路 以一个点作为平角 计算几何统计 c o d e code code include
  • 2021CCPC河南省赛题解(主席树+二分)

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

    Problem poj org problem id 2155 vjudge net contest 146952 problem A Referencd www cnblogs com gj Acit p 3258880 html Mea
  • hdu 5756:Boss Bo

    题目链接如下 Problem 5756 先用dfs确定每个节点的序号编号 并且可以获得每个节点可以包括的子树节点区间范围 再用线段树建立一棵树 在第一次建立的时候我们记录每个节点的深度 然后再进行一次dfs 这次dfs用来更新以不同节点为根
  • 豪斯多夫距离-- Hausdorff distance of convex polygons

    蒙特利尔的麦吉尔大学的计算几何课程资料 原文链接 http cgm cs mcgill ca godfried teaching cg projects 98 normand main html 1 Introduction When ta
  • 判断一个点是否在圆内(三点确定一个圆)

    三角形的外接圆圆心是任意两边的垂直平分线的交点 三角形外接圆圆心叫外心
  • XOR TREE【牛客练习赛58 F】【树链剖分】

    题目链接 这个问题很容易想到之间的关系 假设现在所要查询的这条链上有V1 V2 VK个点 那么第i个点的贡献在抑或中出现的次数XOR为 当K为偶数时候 F i 恒定为奇数 当K为奇数的时候 F i 在i为偶数的时候F i 为奇数 只有F i

随机推荐

  • 数据库中表数据备份

    目的 在所有的数据仓库类项目中几乎都会涉及到数据库中表数据备份的操作 主要是为了对一些结果数据进行备份 防止误操作 过程 一 背景 本次我们用的方法是通过在数据库中建立一个备份用户进行数据备份的操作 原因是现在的数据库一般是基于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空间机构有一个雄心勃勃的计划 他们想制作一张整个行星的地图 为了考虑必要的工作 他们需要知道地图上已经存在的全部区域的大