当前位置: 首页 > news >正文

刷题记录:牛客NC25078[USACO 2007 Ope S]City Horizon

传送门:牛客

题目描述:

Farmer John has taken his cows on a trip to the city! As the sun sets, the cows gaze at the city horizon and 
observe the beautiful silhouettes formed by the rectangular buildings.
The entire horizon is represented by a number line with N (1 ≤ N ≤ 40,000) buildings. Building i's silhouette has 
a base that spans locations Ai through Bi along the horizon (1 ≤ Ai < Bi ≤ 1,000,000,000) and has height Hi (1 ≤ 
Hi ≤ 1,000,000,000). Determine the area, in square units, of the aggregate silhouette formed by all N buildings.
输入:
4
2 5 1
9 10 4
6 8 2
4 6 3
输出;
16

经典的多个矩形覆盖求总面积问题.需要使用扫描线算法进行解决.

对于扫描线算法,网上有大量博客对此进行讲解,此处就不在赘述了

为各位在提供一个有关这道题的另一种题面(不要换了题面就不会做了):

有一个数列,初始值均为0,他进行N次操作,每次将数列[ai,bi)这个区间中所有比Hi小的数改为Hi,他想知道N次操作后数列中所有元素的和。

看了这个题面有没有感觉扫描线的一些神奇之处??感觉有点积分的思想在那里了,反正我刚开始看到这道题(当我学完扫描线之后),我当时仍然是不知道怎么做的,根本就没有往扫描线那里想,还在想该怎么维护这道题.

优化&巧妙的想法:对于这种只需要区间[1,n]的维护值来说,我们建立线段树的时候可以不使用pushdown(因为我们根本不需要关注子节点是怎么样的),在子节点pushup的时候将父节点对子节点的lazy加上即可.
注意,此方法在我看来并不具有很强的意义,虽然省去了对子节点的维护,码量减少了,但是因为这种方式大大的修改了模板,会导致出现一写奇奇怪怪的错误甚至思维上的混乱,但是在平时可以挑战一下,这样改变常规的做法可以大大增强自己对线段树的理解

下面是具体的代码部分(标准版维护版):

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define root 1,n,1
#define ls rt<<1
#define rs rt<<1|1
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
inline ll read() {ll x=0,w=1;char ch=getchar();for(;ch>'9'||ch<'0';ch=getchar()) if(ch=='-') w=-1;for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0';return x*w;
}
#define int long long
#define maxn 1000000
const double eps=1e-8;
#define	int_INF 0x3f3f3f3f
#define ll_INF 0x3f3f3f3f3f3f3f3f
struct Segment_tree{int l,r,cov,lazy;
}tree[maxn*8];
struct Line{int l,r,y,cate;bool operator < (const Line &rhs) const {return y<rhs.y;}
}line[maxn];
int n;vector<int>v;
int Get_id(int x) {return lower_bound(v.begin(),v.end(),x)-v.begin()+1;
}
void build(int l,int r,int rt) {tree[rt].l=l;tree[rt].r=r;if(l==r) return ;int mid=(l+r)>>1;build(lson);build(rson);
}
void pushup(int rt) {tree[rt].cov=min(tree[ls].cov,tree[rs].cov);
}
void change(int rt,int val) {tree[rt].cov+=val;tree[rt].lazy+=val;
}
void pushdown(int rt) {change(ls,tree[rt].lazy);change(rs,tree[rt].lazy);tree[rt].lazy=0;
}
void update(int l,int r,int val,int rt) {if(tree[rt].l==l&&tree[rt].r+1==r) {change(rt,val);return ;}if(tree[rt].lazy) pushdown(rt);int mid=(tree[rt].l+tree[rt].r)>>1;if(r<=mid+1) update(l,r,val,ls);else if(l>=mid+1) update(l,r,val,rs);else update(l,mid+1,val,ls),update(mid+1,r,val,rs);pushup(rt);
}
int query(int l,int r,int rt) {if(tree[rt].l==l&&tree[rt].r+1==r) {if(tree[rt].cov) return v[r-1]-v[l-1];else if(tree[rt].l==tree[rt].r) return 0; }if(tree[rt].lazy) pushdown(rt);int mid=(tree[rt].l+tree[rt].r)>>1;if(r<=mid+1) return query(l,r,ls);else if(l>=mid+1) return query(l,r,rs);else return query(l,mid+1,ls)+query(mid+1,r,rs);
}
signed main() {n=read();int cnt=0;for(int i=1;i<=n;i++) {int a=read(),b=read(),h=read();line[++cnt].l=a;line[cnt].r=b;line[cnt].y=0;line[cnt].cate=1;line[++cnt].l=a;line[cnt].r=b;line[cnt].y=h;line[cnt].cate=-1;v.push_back(b);v.push_back(a);}sort(line+1,line+2*n+1);sort(v.begin(),v.end());v.erase(unique(v.begin(),v.end()),v.end());int Size=v.size();build(1,Size,1);int ans=0;for(int i=1;i<=2*n-1;i++) {int x1=Get_id(line[i].l),x2=Get_id(line[i].r);update(x1,x2,line[i].cate,1);ans+=query(1,Size,1)*(line[i+1].y-line[i].y);}cout<<ans<<endl;return 0;
}

下面是具体的代码部分(不维护pushdownpushdownpushdown版):

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define root 1,n,1
#define ls rt<<1
#define rs rt<<1|1
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
inline ll read() {ll x=0,w=1;char ch=getchar();for(;ch>'9'||ch<'0';ch=getchar()) if(ch=='-') w=-1;for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0';return x*w;
}
#define int long long
#define maxn 1000000
const double eps=1e-8;
#define	int_INF 0x3f3f3f3f
#define ll_INF 0x3f3f3f3f3f3f3f3f
struct Segment_tree{int l,r,cov,len;
}tree[maxn*4];
int n;vector<int>v;
int Get_id(int x) {return lower_bound(v.begin(),v.end(),x)-v.begin()+1;
}
struct Line{int l,r,y,cate;bool operator < (const Line &rhs) const {return y<rhs.y;}
}line[maxn];
void build(int l,int r,int rt) {tree[rt].l=l;tree[rt].r=r;if(l==r) return ;int mid=(l+r)>>1;build(lson);build(rson);
}
void pushup(int rt) {if(tree[rt].cov) tree[rt].len=v[tree[rt].r]-v[tree[rt].l-1];else tree[rt].len=tree[ls].len+tree[rs].len;
}
void update(int l,int r,int val,int rt) {if(tree[rt].l==l&&tree[rt].r+1==r) {tree[rt].cov+=val;if(tree[rt].cov) tree[rt].len=v[r-1]-v[l-1];else pushup(rt);return ;}int mid=(tree[rt].l+tree[rt].r)>>1;if(r<=mid+1) update(l,r,val,ls);else if(l>=mid+1) update(l,r,val,rs);else update(l,mid+1,val,ls),update(mid+1,r,val,rs);pushup(rt);
}
signed main() {n=read();int cnt=0;for(int i=1;i<=n;i++) {int a=read(),b=read(),h=read();line[++cnt].l=a;line[cnt].r=b;line[cnt].y=0;line[cnt].cate=1;line[++cnt].l=a;line[cnt].r=b;line[cnt].y=h;line[cnt].cate=-1;v.push_back(b);v.push_back(a);}sort(line+1,line+2*n+1);sort(v.begin(),v.end());v.erase(unique(v.begin(),v.end()),v.end());int Size=v.size();build(1,Size,1);int ans=0;for(int i=1;i<=2*n-1;i++) {int x1=Get_id(line[i].l),x2=Get_id(line[i].r);update(x1,x2,line[i].cate,1);ans+=tree[1].len*(line[i+1].y-line[i].y);}cout<<ans<<endl;return 0;
}

相关文章:

刷题记录:牛客NC25078[USACO 2007 Ope S]City Horizon

传送门:牛客 题目描述: Farmer John has taken his cows on a trip to the city! As the sun sets, the cows gaze at the city horizon and observe the beautiful silhouettes formed by the rectangular buildings. The entire horizon is represented by a number line …...

【Java|golang】 1238. 循环码排列---格雷编码

给你两个整数 n 和 start。你的任务是返回任意 (0,1,2,…,2^n-1) 的排列 p&#xff0c;并且满足&#xff1a; p[0] start p[i] 和 p[i1] 的二进制表示形式只有一位不同 p[0] 和 p[2^n -1] 的二进制表示形式也只有一位不同 示例 1&#xff1a; 输入&#xff1a;n 2, start …...

Python自动化测试框架封装和调用

封装与调用函数与参数化前言 面实现了参数的关联&#xff0c;那种只是记流水账的完成功能&#xff0c;不便于维护&#xff0c;也没什么可读性&#xff0c;接下来这篇可以把每一个动作写成一个函数&#xff0c;这样更方便了。参数化的思维只需记住一点&#xff1a;不要写死 登录…...

线程的执行

承接上文CPU原理简介程序的执行是由控制器发信号推动整个程序一步一步向前走&#xff0c;将数据存储在寄存器&#xff0c;从程序计数器中获取指令&#xff0c;比如先把3放到寄存器&#xff0c;再把5放到寄存器&#xff0c;再做一个加法&#xff0c;加法就是一个指令&#xff0c…...

【视频】海康摄像头、NVR网络协议简介

1、软硬件整体架构 2、涉及的网络协议 3、协议简介 3.1 海康私有协议 设备发现SADP:进行设备的发现、激活、修改网络参数、忘记密码等; SDK:4200、系统平台的接入前端设备,协议不对外开放,但对外提供接口库; ISAPI:Intelligent Security API(智能安全API),基于HTTP传输…...

【Spring的事务传播行为有哪些呢?Spring事务的隔离级别?讲下嵌套事务?】

如果你想寻求一份与后端相关的开发工作&#xff0c;那么关于Spring事务相关的面试题你就不能说不会并且不能不知道&#xff1f; 人生如棋&#xff0c;我愿为卒&#xff0c;行动虽慢&#xff0c;可谁曾见我后退一步&#xff1f; 一.Spring中声明事务的方式 1.1 编程式事务 编程…...

其实一点不难学会这三步一定让你学会制作一个『3D建模』大屏

上次已经教过大家怎样制作一个简单的2D数据可视化大屏~那有一些朋友们就会说那些炫酷的3D可视化大屏是怎样制作的呢&#xff1f;这不就来了&#xff0c;今天就教大家怎样用山海鲸可视化软件制作一个带3D建模的可视化大屏&#xff0c;并且最重要的是无需会特别复杂的3D建模知识。…...

【C++】C++的内存模型之四大分区

程序的内存模型 C程序在执行时&#xff0c;将内存大方向划分为4个区域 代码区&#xff1a;存放函数体的二进制代码&#xff0c;由操作系统进行管理的全局区&#xff1a;存放全局变量和静态变量以及常量栈区&#xff1a;由编译器自动分配释放&#xff0c;存放函数的参数值&…...

Vue跨级通信(重点)

当不使用Vuex的前提下&#xff0c;子孙传递就得使用另外一种办法&#xff1a;provide 和 inject 总结&#xff1a;provide / inject 类似于消息的订阅和发布。- inject接收数据。- provide提供或发送数据&#xff0c;&#xff08;1&#xff09;provide&#xff08;name&#xf…...

支付系统中的设计模式07:责任链模式

最近公司业务的发展果然如老板当初所画(预)饼(言)的那样红(恍)红(恍)火(惚)火(惚),蒸蒸日上,每天的流水都在不断攀升到新的高度,有不少人都从公司开发的电商平台挣到了钱。 不过问题也接着来了——运营部门经过老板的同意,也学着产品经理提出了下面几项非常合理…...

期末综合考试

一、概率论1、全概率公式、贝叶斯公式应用2、期望、方差、协方差的定义以及性质证明(1) 期望(2) 方差(3) 协方差二、数理统计1、参数估计(1) 矩估计(2) 最大似然估计(3) 综合例题一、概率论 1、全概率公式、贝叶斯公式应用 记住标黄的两段&#xff0c;上考场直接套数据&#x…...

数据结构与算法之爬楼梯动态规划

一.题目(爬楼梯)假设你正在爬楼梯。需要 n 阶你才能到达楼顶。每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢&#xff1f;注意&#xff1a;给定 n 是一个正整数。示例 1&#xff1a;输入&#xff1a; 2输出&#xff1a; 2解释&#xff1a; 有两种方法可以爬…...

CleanMyMac4.12最新Mac电脑系统垃圾清理神器

CleanMyMac是Mac一款神器&#xff0c;特别是清理已卸载软件残留垃圾文件信息库比较全面。 clearmymac以极其快速和时尚的方式为您提供及时的建议&#xff0c;组织&#xff0c;更新和保护您的Mac。完全支持macOS 11&#xff08;Big Sur&#xff09;操作系统&#xff1b;它以其简…...

数据治理如何做?火山引擎 DataLeap 帮助这款产品 3 个月降低计算成本 20%

更多技术交流、求职机会&#xff0c;欢迎关注字节跳动数据平台微信公众号&#xff0c;回复【1】进入官方交流群 本文讲述字节跳动一款 App 产品的数据治理故事。该产品随着用户体量和数据体量不断增长&#xff0c;数仓的任务量、数据量也不断攀升&#xff0c;运维难、成本贵、稳…...

求职3个月,简历大多都石沉大海,一听是手工测试都纷纷摇头....太难了

距离被上家公司裁员已经过去了3个月了&#xff0c;3个月的求职经历真的让我痛不欲生&#xff0c;我也从中理解感叹到了很多&#xff0c;想写出来&#xff0c;告诫跟我一样的经历的人。 我今年26岁&#xff0c;大学是一所普通的大专&#xff0c;学的是机电专业&#xff0c;如何…...

Visual Studio快捷键汇总

常用快捷键CtrlEC 注释代码CtrlEU 取消注释代码CtrlED 格式化全部代码CtrlShiftA 新建类CtrlRG 删除无效UsingCtrlH 批量替换CtrlG 跳转到指定行CtrlEE 在交互窗口中运行选中代码(很实用)AltEnter 快速引用shiftF9 监控(代码运行时)shiftF6 生成(当前类库)F6 生成(整个解决方案…...

ctf pwn基础-2

今天学了一个保护的绕过&#xff0c;这里讲一讲&#xff0c;这个好像是使用的是格式化字符串漏洞。 目录 基础 实例讲解 基础 首先我们要知道什么是canary保护&#xff0c;就是在入栈EBP以后加一个Canary 我可能讲的不是很好&#xff0c;大家可以看看这些 文章 用通俗一点将就…...

从一个SQL打印全年日历漫谈数据仓库中时间操作场景的重点写法

文章目录前言一、我如何快速确定今年是否是闰年的&#x1f623;二、 我如何从DATE类型数据获取年、月(月初&月末)、周、日、时、分、秒信息&#x1f92f;三、我如何快速查到本月月初第一周的周一和本月最后一周周一是在几号&#x1f611;四、我如何快速确定每个季度的开始和…...

Java跳槽涨薪之路-想学Java的赶紧上车了

前言Java 是近 10 年来计算机软件发展过程中的传奇&#xff0c;在很多开发者心中的地位可谓“爱不释手”&#xff0c;与其他一些计算机语言随着时间的流逝影响也逐渐减弱不同&#xff0c;Java 随着时间的推移反而变得更加强大。按应用范围&#xff0c;Java 可分为 3 个体系&…...

MyBatis解析全局配置文件

目录 MyBatis介绍 传统JDBC和Mybatis相比的弊病 传统JDBC的问题如下 mybatis对传统的JDBC的解决方案 Mybaits整体体系图 使用大致过程 MyBatis 源码编译 源码解析 配置文件解析 读取配置文件 返回SqlSessionFactory 配置文件内容 解析的核心方法 解析出来的对象 …...

内存分配函数malloc kmalloc vmalloc

内存分配函数malloc kmalloc vmalloc malloc实现步骤: 1)请求大小调整:首先,malloc 需要调整用户请求的大小,以适应内部数据结构(例如,可能需要存储额外的元数据)。通常,这包括对齐调整,确保分配的内存地址满足特定硬件要求(如对齐到8字节或16字节边界)。 2)空闲…...

【人工智能】神经网络的优化器optimizer(二):Adagrad自适应学习率优化器

一.自适应梯度算法Adagrad概述 Adagrad&#xff08;Adaptive Gradient Algorithm&#xff09;是一种自适应学习率的优化算法&#xff0c;由Duchi等人在2011年提出。其核心思想是针对不同参数自动调整学习率&#xff0c;适合处理稀疏数据和不同参数梯度差异较大的场景。Adagrad通…...

Nuxt.js 中的路由配置详解

Nuxt.js 通过其内置的路由系统简化了应用的路由配置&#xff0c;使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...

html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码

目录 一、&#x1f468;‍&#x1f393;网站题目 二、✍️网站描述 三、&#x1f4da;网站介绍 四、&#x1f310;网站效果 五、&#x1fa93; 代码实现 &#x1f9f1;HTML 六、&#x1f947; 如何让学习不再盲目 七、&#x1f381;更多干货 一、&#x1f468;‍&#x1f…...

GruntJS-前端自动化任务运行器从入门到实战

Grunt 完全指南&#xff1a;从入门到实战 一、Grunt 是什么&#xff1f; Grunt是一个基于 Node.js 的前端自动化任务运行器&#xff0c;主要用于自动化执行项目开发中重复性高的任务&#xff0c;例如文件压缩、代码编译、语法检查、单元测试、文件合并等。通过配置简洁的任务…...

JavaScript基础-API 和 Web API

在学习JavaScript的过程中&#xff0c;理解API&#xff08;应用程序接口&#xff09;和Web API的概念及其应用是非常重要的。这些工具极大地扩展了JavaScript的功能&#xff0c;使得开发者能够创建出功能丰富、交互性强的Web应用程序。本文将深入探讨JavaScript中的API与Web AP…...

小木的算法日记-多叉树的递归/层序遍历

&#x1f332; 从二叉树到森林&#xff1a;一文彻底搞懂多叉树遍历的艺术 &#x1f680; 引言 你好&#xff0c;未来的算法大神&#xff01; 在数据结构的世界里&#xff0c;“树”无疑是最核心、最迷人的概念之一。我们中的大多数人都是从 二叉树 开始入门的&#xff0c;它…...

沙箱虚拟化技术虚拟机容器之间的关系详解

问题 沙箱、虚拟化、容器三者分开一一介绍的话我知道他们各自都是什么东西&#xff0c;但是如果把三者放在一起&#xff0c;它们之间到底什么关系&#xff1f;又有什么联系呢&#xff1f;我不是很明白&#xff01;&#xff01;&#xff01; 就比如说&#xff1a; 沙箱&#…...

VisualXML全新升级 | 新增数据库编辑功能

VisualXML是一个功能强大的网络总线设计工具&#xff0c;专注于简化汽车电子系统中复杂的网络数据设计操作。它支持多种主流总线网络格式的数据编辑&#xff08;如DBC、LDF、ARXML、HEX等&#xff09;&#xff0c;并能够基于Excel表格的方式生成和转换多种数据库文件。由此&…...

算法打卡第18天

从中序与后序遍历序列构造二叉树 (力扣106题) 给定两个整数数组 inorder 和 postorder &#xff0c;其中 inorder 是二叉树的中序遍历&#xff0c; postorder 是同一棵树的后序遍历&#xff0c;请你构造并返回这颗 二叉树 。 示例 1: 输入&#xff1a;inorder [9,3,15,20,7…...