[NOIP2012 提高组] 借教室

news2024/12/23 15:45:56

[NOIP2012 提高组] 借教室

题目描述:

在大学期间,经常需要租借教室。大到院系举办活动,小到学习小组自习讨论,都需要向学校申请借教室。教室的大小功能不同,借教室人的身份不同,借教室的手续也不一样。

面对海量租借教室的信息,我们自然希望编程解决这个问题。

我们需要处理接下来 n 天的借教室信息,其中第 i 天学校有 ri​ 个教室可供租借。共有 m 份订单,每份订单用三个正整数描述,分别为 dj​,sj​,tj​,表示某租借者需要从第 sj​ 天到第 tj​ 天租借教室(包括第 sj​ 天和第 tj​ 天),每天需要租借 dj​ 个教室。

我们假定,租借者对教室的大小、地点没有要求。即对于每份订单,我们只需要每天提供 dj​ 个教室,而它们具体是哪些教室,每天是否是相同的教室则不用考虑。

借教室的原则是先到先得,也就是说我们要按照订单的先后顺序依次为每份订单分配教室。如果在分配的过程中遇到一份订单无法完全满足,则需要停止教室的分配,通知当前申请人修改订单。这里的无法满足指从第 sj​ 天到第 tj​ 天中有至少一天剩余的教室数量不足 dj​ 个。

现在我们需要知道,是否会有订单无法完全满足。如果有,需要通知哪一个申请人修改订单。

输入格式

第一行包含两个正整数 n,m,表示天数和订单的数量。

第二行包含 n 个正整数,其中第 i 个数为 ri​,表示第 i 天可用于租借的教室数量。

接下来有 m 行,每行包含三个正整数 dj​,sj​,tj​,表示租借的数量,租借开始、结束分别在第几天。

每行相邻的两个数之间均用一个空格隔开。天数与订单均用从 1 开始的整数编号。

输出格式

如果所有订单均可满足,则输出只有一行,包含一个整数 0。否则(订单无法完全满足)

输出两行,第一行输出一个负整数 -1,第二行输出需要修改订单的申请人编号。

输入输出样例

输入 #1:

4 3 
2 5 4 3 
2 1 3 
3 2 4 
4 2 4

输出 #1:

-1 
2

说明/提示

【输入输出样例说明】

第 1份订单满足后,4天剩余的教室数分别为 0,3,2,3。第 2 份订单要求第 2天到第 4 天每天提供3个教室,而第 3 天剩余的教室数为2,因此无法满足。分配停止,通知第 2 个申请人修改订单。

【数据范围】

对于10%的数据,有1≤ n,m≤ 10;

对于30%的数据,有1≤ n,m≤1000;

对于 70%的数据,有1 ≤ n,m ≤ 10^5;

对于 100%的数据,有1≤n,m≤10^6,0≤ri​,dj​≤10^9,1≤sj​≤tj​≤n。

NOIP 2012 提高组 第二天 第二题

2022.2.20 新增一组 hack 数据

思路:

  一、暴力简述

首先我们不难看出,这道题————并不是一道多难的题,因为显然,第一眼看题目时便很容易地想到暴力如何打:枚举每一种订单,然后针对每一种订单,对区间内的每一天进行修改(做减法),直到某一份订单使得某一天剩下的教室数量为负数,即可得出结果。

先小小的评析一下吧:凡是能打出几近正解的暴力题,都不是难题!(蒟蒻可以骗到50+的不就是水题吗qwq)但是,显然枚举形式的暴力会很慢,期望的时间复杂度约为

                                                                  O(N * M)

可能会更快一些(但没卵用qwq


二、思想详述

  让我们开动脑筋想一下:每张订单其实就可以看作是一个区间(操作),左右区间分别为开始时间和结束时间,所以这不就是一个区间操作吗——首选线段tree啦!但是笔者在这里并不打算介绍线段树,因为虽然线段tree操作方便、复杂度低,但是——————代码也忒儿长了些吧qwq!(逃

  并且总感觉你考试的时候撸一个线段树模板的时间完全可以多打两个暴力啊qwq(虽然暴力也不一定对

  所以,选择引入一种好理解、好实现的算法:差分数组

  在介绍差分之前,需要介绍前缀和思想

(qwq此处当然只会讲一维线性的前缀和啦)

  **我们有一组数(个数小于等于一千万),并且有一大堆询问——给定区间l、r,求l、r之间所有数之和(询问个数小于等于一千万) **

  此处暴力肯定不行啊(O(NQlength)),那么我们来观察前缀和是怎么做的:用sum[i]来存储前i个数的和,然后用sum[r]-sum[l-1]来表示l~r之间所有数的和。(l-1原因是l~r只看要包含l)而sum数组便可以通过简单的递推求出来

代码核心:

for(int i=1;i<=n;i++){
    cin>>a[i];
    sum[i]=sum[i-1]+a[i];
}
for(int i=1;i<=q;i++){
    cin>>l>>r;
    cout<<sum[r]-sum[l-1]<<" ";
}

而所谓的差分数组,即是前缀和数组的逆运算:

我们给定前i个数相邻两个数的差(1<=i<=n),求每一项a[i](1<=i<=n)。

此时无非就是用作差的方式求得每一项,此时我们可以有一个作差数组diff,diff[i]用于记录a[i]-a[i-1],然后对于每一项a[i],我们可以递推出来:

for(int i=1;i<=n;i++){
    cin>>diff[i];
    a[i]=diff[i]+a[i-1];
}
for(int i=1;i<=n;i++)
  cout<<a[i]<<' ';

到这儿,我们可以看出来,前缀和是用元数据求元与元之间的并集关系,而差分则是根据元与元之间的逻辑关系求元数据,是互逆思想(qwq但是有时元数据和关系数据不是很好辨别或者产生角色反演啊)

但是,理解了前缀和&差分,并不代表肯定能做到模板题:毕竟,思想只能是辅助工具


三、关于二分答案

  一般来说,二分是个很有用的优化途径,因为这样会直接导致减半运算,而对于能否二分,有一个界定标准:状态的决策过程或者序列是否满足单调性或者可以局部舍弃性。 而在这个题里,因为如果前一份订单都不满足,那么之后的所有订单都不用继续考虑;而如果后一份订单都满足,那么之前的所有订单一定都可以满足,符合局部舍弃性,所以可以二分订单数量。 

四、正解!

首先,要明白如为什么要用区间差分而不是区间前缀和:因为这个题每次操作针对的对象都是原本题目中给的元数据,而不是让求某个关系,所以采用差分。

其次,要知道差分会起到怎样的作用:因为diff数组决定着每个元数据的变化大小、趋势,所以,当我们想要针对区间操作时,钱可以转化成对diff数组操作:

diff[l[i]]+=d[i];
diff[r[i]+1]-=d[i];//d[i]是指每天要借的教室数

因为后面的元数据都由之前的diff数组推导出来,所以改变diff[i]就相当于改变i之后的每一个值,并通过重新减去改变的量,达到操作区间的目的。

then,我们需要想明白策略:从第一份订单开始枚举,直到无法满足或者全枚举完结束。

最后,一点提示,我下面的标程是通过比大小来判断是否满足,而不是作差判负数————能不出负数就别出负数。

完整代码:
 

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N=1000011;
ll r[N],sum[N],ID=0,d[N],s[N],t[N],a[N];
ll n,m;
bool pd(ll mid){
	memset(sum,0,sizeof(sum));
	for(ll i=1;i<=mid;i++){
		sum[s[i]]+=d[i];
		sum[t[i]+1]-=d[i];
	}
	for(ll i=1;i<=n;i++){
		a[i]=a[i-1]+sum[i];
		if(a[i]>r[i])
		  return false;
	}
	return true;
}
int main(){
	scanf("%d%d",&n,&m);
	bool f=true;
	for(ll i=1;i<=n;i++)
	  cin>>r[i];
	for(ll i=1;i<=m;i++)
	  cin>>d[i]>>s[i]>>t[i];
	ll x=1,y=m;
	if(pd(m)){
		cout<<"0"<<'\n';
		exit(0);
	}
	else{
		while(x<y){
			ll mid=(x+y)/2;
			if(pd(mid))
			  x=mid+1;
			else
			  y=mid;
		}		
	}
	cout<<"-1"<<'\n'<<x<<'\n';
	return 0;
} 

总结:

  在这道题里面,我们看到了差分及前缀和的应用,既然差分与前缀和都行,那么我们可以热烈欢迎线段树(树状貌似也还行?)做法……

题目链接:

[NOIP2012 提高组] 借教室 - 洛谷https://www.luogu.com.cn/problem/P1083#sub

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/638532.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【深度学习】pytorch pth模型转为onnx模型后出现冗余节点“identity”,onnx模型的冗余节点“identity”

情況描述 onnx模型的冗余节点“identity”如下图。 解决方式 首先&#xff0c;确保您已经安装了onnx-simplifier库&#xff1a; pip install onnx-simplifier然后&#xff0c;您可以按照以下方式使用onnx-simplifier库&#xff1a; import onnx from onnxsim import simp…

手机短视频设置背景文字工具

代码地址 github: https://github.com/iotzzh/tools-web gitee: https://gitee.com/iotzzh/tools-web.git 以前喜欢发抖音&#xff0c;内容是一些古诗文&#xff0c;然后找不到合适模板&#xff0c;于是自己就写了一个小工具&#xff0c;功能如下&#xff1a; 时间展示、支持选…

爬虫基础学习记录

爬虫介绍 互联网爬虫 如果我们把互联网比作一张大的蜘蛛网&#xff0c;那一台计算机上的数据便是蜘蛛网上的一个猎物&#xff0c;而爬虫程序就是一只小蜘蛛&#xff0c;沿着蜘蛛网抓取自己想要的数据 解释1&#xff1a;通过一个程序&#xff0c;根据Url(http://www.taobao.c…

❤ vue主要使用的版本和对应体系

❤ 项目主要使用的版本和对应体系 vue地址&#xff1a; https://cn.vuejs.org/ Vue所有版本地址 https://github.com/vuejs/core/blob/main/changelogs/CHANGELOG-3.2.md NPM镜像地址 npm install -g cnpm --registryhttps://registry.npm.taobao.org nvm 地址&#xff1a; htt…

element(兼容2.72以下的版本)实现树形数据+复选框的效果

用最新的element是可以实现树形数据的展示&#xff0c;但是没有复选框效果&#xff0c;用2.72以前的版本的话&#xff0c;是根本没有展开树形数据的效果&#xff0c;也没有复选框效果&#xff0c; 需求&#xff1a;在2.72以下的老版本上做一个树形展示的效果&#xff0c;并且还…

初识Notes Domino 14 Drop1

大家好&#xff0c;才是真的好。 周末花了点时间&#xff0c;安装了一下Notes Domino 14 Drop1版本。考虑到大多数人的习惯&#xff0c;没采用Docker或K8s方式来部署&#xff0c;也没采用一键配置功能&#xff0c;依旧通过传统方式一步一步进行安装和配置&#xff0c;这样大家…

【Spring Boot 初识丨五】beans 详解

上一篇讲了 Spring Boot 的主程序类 本篇来讲一讲 beans 详解 Spring Boot 初识&#xff1a; 【Spring Boot 初识丨一】入门实战 【Spring Boot 初识丨二】maven 【Spring Boot 初识丨三】starter 【Spring Boot 初识丨四】主应用类 beans 一、 定义二、 命名三、 生命周期3.1 …

Linux防火墙学习笔记7

安装apahce&#xff1a; yum install -y httpd echo 123 >> /var/www/html/index.html systemctl start httpd curl http://localhost 然后给iptables插入一条防火墙策略&#xff1a; iptables -t filter -I INPUT -p tcp --dport 80 -j ACCEPT注意&#xff1a;这里使…

【Spring学习之更简单的读取和存储Bean对象】教会你使用五大类注解和方法注解去存储 Bean 对象

前言&#xff1a; &#x1f49e;&#x1f49e;今天我们依然是学习Spring&#xff0c;这里我们会更加了解Spring的知识&#xff0c;知道Spring是怎么更加简单的读取和存储Bean对象的。也会让大家对Spring更加了解。 &#x1f49f;&#x1f49f;前路漫漫&#xff0c;希望大家坚持…

高能预警!融云WICC发布《社交泛娱乐出海作战地图》

最近圈子里风很大的《社交泛娱乐出海作战地图》, 必须说&#xff0c;真的有亿点点厉害&#xff01;这简直是一张集社交泛娱乐市场、品类知识和出海实战指南于一体的教材级地图&#xff0c;实感入手不亏。关注【融云全球互联网通信云】了解更多 首先&#xff0c;容我先秀一把实…

Definition of regularity in PDE theory

Regularity is one of the vague yet very useful terms to talk about a vast variety of results in a uniform way. Other examples of such words include “dynamics” in dynamical systems (I have never seen a real definition of this term but everyone uses it, an…

学习Vue 之 创建一个 Vue 应用

文章目录 Vue.js概述了解 Vue创建一个 Vue 应用参考 Vue.js 概述 计划学习前端&#xff0c;已有一些HTML&#xff0c;js&#xff0c;CSS的基础知识&#xff0c;下一步学习Vue.js。 以下是一些适合新手的Vue.js教程&#xff0c;你可以根据自己的实际情况和需求选择适合自己的…

独家揭秘:Kotlin编译器前端—解析阶段

独家揭秘&#xff1a;Kotlin编译器前端&#xff1a;解析阶段 Kotlin编译器对我来说就像一个黑盒子&#xff0c;虽然有关于Kotlin PSI在IDE插件中有使用的文档&#xff0c;但除了源代码中留下的注释之外&#xff0c;几乎没有其他信息可用。接下来的文章中我们来探索Kotlin编译器…

6. WebGPU 将图像导入纹理

我们在上一篇文章中介绍了有关使用纹理的一些基础知识。在本文中&#xff0c;我们将介绍从图像导入纹理。 在上一篇文章中&#xff0c;通过调用 device.createTexture 创建了一个纹理&#xff0c;然后通过调用 device.queue.writeTexture 将数据放入纹理中。 device.queue 上还…

Axure教程—穿梭框(中继器+动态面板)

本文将教大家如何用AXURE中动态面板和中继器制作穿梭框效果 一、效果 预览地址&#xff1a;https://8k99mh.axshare.com 下载地址&#xff1a;https://download.csdn.net/download/weixin_43516258/87897661?spm1001.2014.3001.5503 二、功能 在待选区域选项中可以选择一个选…

CURL获取与使用

背景&#xff1a;在日常工作中&#xff0c;经常会遇到需要获取CURL构造请求来进行问题定位&#xff0c;那如何获取及使用CURL则成为一个测试人员必备的技能&#xff1b; CURL是什么 CURL是一个命令行工具&#xff0c;开发人员使用它来与服务器进行数据交互。 如何获取完整 C…

Python开源自动化工具Playwright安装及介绍

目录 前言 1、Playwright介绍 2、Playwright安装 3、实操演示 4、小结 总结&#xff1a; 前言 微软开源了一个非常强大的自动化项目叫 playwright-python 它支持主流的浏览器&#xff0c;包含&#xff1a;Chrome、Firefox、Safari、Microsoft Edge 等&#xff0c;同时支…

简单使用Hystrix

使用Hystrix之前&#xff0c;需要先对SpringCloud有所了解&#xff0c;然后才会使用的顺畅&#xff0c;它是我们SpringCould的一种保护机制&#xff0c;非常好用。 下面直接开始 先导入Hystrix所需要的依赖 <!-- 引入openfiegn--> <dependency> <groupId>org…

Java学习笔记(视频:韩顺平老师)3.0

如果你喜欢这篇文章的话&#xff0c;请给作者点赞哟&#xff0c;你的支持是我不断前进的动力。 因为作者能力水平有限&#xff0c;欢迎各位大佬指导。 目录 如果你喜欢这篇文章的话&#xff0c;请给作者点赞哟&#xff0c;你的支持是我不断前进的动力。 算数运算符 号使用…

体验 TDengine 3.0 高性能的第一步,请学会控制建表策略

正如我们之前所言&#xff0c;在 3.0 当中&#xff0c;我们在产品底层做了很大的变化调整&#xff0c;除了架构更加科学高效以外&#xff0c;用户体验也是我们重点优化的方向。以之前一篇文章为例&#xff1a;对于 Update 功能&#xff0c;用户不再需要任何配置 &#xff0c;默…