2024/3/10打卡借教室——二分+差分

题目

在大学期间,经常需要租借教室。

大到院系举办活动,小到学习小组自习讨论,都需要向学校申请借教室。

教室的大小功能不同,借教室人的身份不同,借教室的手续也不一样。 

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

我们需要处理接下来 n 天的借教室信息,其中第 i 天学校有 ri 个教室可供租借。

共有 m 份订单,每份订单用三个正整数描述,分别为 d_j,s_j,t_j,表示某租借者需要从第 s_j 天到第 t_j 天租借教室(包括第 s_j 天和第 t_j 天),每天需要租借 d_j 个教室。 

我们假定,租借者对教室的大小、地点没有要求。

即对于每份订单,我们只需要每天提供 d_j 个教室,而它们具体是哪些教室,每天是否是相同的教室则不用考虑。 

借教室的原则是先到先得,也就是说我们要按照订单的先后顺序依次为每份订单分配教室。

如果在分配的过程中遇到一份订单无法完全满足,则需要停止教室的分配,通知当前申请人修改订单。

这里的无法满足指从第 s_j 天到第 t_j 天中有至少一天剩余的教室数量不足 d_j 个。 

现在我们需要知道,是否会有订单无法完全满足。

如果有,需要通知哪一个申请人修改订单。

输入格式

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

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

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

每行相邻的两个数之间均用一个空格隔开。

天数与订单均用从 1 开始的整数编号。

输出格式

如果所有订单均可满足,则输出只有一行,包含一个整数 0。

否则(订单无法完全满足)输出两行,第一行输出一个负整数 −1,第二行输出第一个需要修改订单的申请人编号。

数据范围

1≤n,m≤10^6,
0≤ri,dj≤10^9,
1≤sj≤tj≤n

输入样例:

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

输出样例:

-1
2

 

思路

        针对每个订单选择某一段连续的天数,来选择教室的个数,可以考虑到用差分来求解。可以将时间复杂度从O(n) 降到 O(1)。 

        差分参考:差分——前缀和的逆运算(一维+二维)-CSDN博客 

         完成每一个订单,每天的可用的教室的数量都是在严格单调下降的,因此可以考虑使用二分,来确定是那个订单导致教室的数量不够用。时间复杂度从O(n^2) 降到 O(nlogn)

        二分参考:二分查找(算法实质+模板)-CSDN博客

        如何通过二分确定订单是否可被满足?通过 check(mid) 计算前 mid 个,包含 mid 在内的所有订单总共 n 天内每天需要的天数(使用差分来计算)  ,如果某天的需要的教室数量大于当天能够分配的教室数量,那么表明该订单不能被满足。再向前走,判断前面的订单能否被满足,r = mid-1;否则,l = mid,找后面的订单能否被满足。

代码(详细注释)

import java.io.*;

class Main{
    static int N = 1000010;
    static int n,m;
    static long[] r = new long[N]; // 每天的教室数量
    static int[] d = new int[N]; // 订单需要的教室数量
    static int[] s = new int[N]; // 订单起始日期
    static int[] t = new int[N]; // 订单终止日期
    public static void main(String[] args) throws IOException{
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        String[] str = in.readLine().split(" ");
        n = Integer.parseInt(str[0]);
        m = Integer.parseInt(str[1]);
        str = in.readLine().split(" ");
        for(int i=1;i<=n;i++){
            r[i] = Long.parseLong(str[i-1]);
        }

        for(int i=1;i<=m;i++){
            str = in.readLine().split(" ");
            d[i] = Integer.parseInt(str[0]);
            s[i] = Integer.parseInt(str[1]);
            t[i] = Integer.parseInt(str[2]);
        }
        // 通过二分,找出第一个不能完全满足订单要求的编号,
        int l = 0, r1 = m; // l需要从0开始,比如说m=1,就不能进行while
        while(l<r1){
            int mid = l+r1+1>>1;
            if(check(mid)) l = mid;
            else r1 = mid-1;
        }
        // 最后的r是满足订单的最后一个
        if(r1==m) System.out.println(0);
        else System.out.println("-1"+"\n"+(r1+1));
        
    }
    public static boolean check(int mid){ // 计算到mid个订单的时候,n天内每天所需的教室的总数,每次都要对前mid个进行总数的计算,b[i]即表示第i天要满足前mid个订单的总数
        long[] b = new long[N];
        
        for(int i=1;i<=mid;i++) // 对所有订单进行差分计算
            insert(b,s[i],t[i],d[i]);
            
        for(int i=1;i<=n;i++){ // 再求差分的前缀和,即每一天需要的教室数量
            b[i] += b[i-1];
            if(b[i]>r[i]) return false;  // 对每一天都需要判断
        }

        return true;
    }
    public static void insert(long[] b,int s,int t,int d){ // 不应该提前计算,会把mid后面的订单也算进去
        b[s] += d;
        b[t+1] -= d;
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

TOMCAT多实例及调优

目录 引言 一、JVM相关理论 &#xff08;一&#xff09;JVM组成 1.JVM组成部分 2.JVM运行时数据区 &#xff08;二&#xff09;垃圾回收 1.确定垃圾 2.垃圾收集算法 二、java内存调整相关参数 &#xff08;一&#xff09;JVM 内存常用相关参数 &#xff08;二&#…

《在“裸奔”时代下如何保护网络隐私》

引言 在信息时代的今天,网络已经成为我们生活中不可或缺的一部分。然而,随着网络的普及和技术的发展,网络安全和隐私保护问题也变得越来越严峻。特别是在这个所谓的“裸奔”时代,我们的个人信息和隐私正面临着前所未有的挑战。因此,保护网络隐私变得尤为重要。 网络安全…

通过Step Back提示增强LLM的推理能力

原文地址&#xff1a;enhancing-llms-reasoning-with-step-back-prompting 论文地址&#xff1a;https://arxiv.org/pdf/2310.06117.pdf 2023 年 11 月 6 日 Introduction 在大型语言模型不断发展的领域中&#xff0c;一个持续的挑战是它们处理复杂任务的能力&#xff0c;这…

el-table 插入输入框并进行校验

<template><div><el-form :model"list" ref"ruleForm"><el-table :data"list.tableData" style"width: 100%"><el-table-column prop"time" label"日期" width"180"><…

【微服务】SpringBoot整合Resilience4j使用详解

目录 一、前言 二、熔断器出现背景 2.1 几个核心概念 2.1.1 熔断 2.1.2 限流 2.1.3 降级 2.2 为什么会出现熔断器 2.3 断路器介绍 2.3.1 断路器原理 三、Resilience4j介绍 3.1 Resilience4j概述 3.1.1 Resilience4j是什么 3.1.2 Resilience4j功能特性 3.2 Resilie…

用关系运算符和表达式比较大小、_Bool类型、for循环

本文参考C Primer Plus第六章进行C语言学习 文章目录 用关系运算符和表达式比较大小 其他真值新的_Bool类型for循环总结 一.用关系运算符和表达式比较大小 虽然关系运算符也可以用来比较浮点数&#xff0c;但是&#xff0c;要注意的是&#xff1a;尽量只使用<和>。因为浮…

【Linux】gcc与make、makefile

文章目录 1 gcc/g1.1 预处理1.2 编译1.3 汇编1.4 链接1.4.1 静态链接1.4.2 动态链接 2 make和makefile2.1 依赖关系2.2 依赖方法2.3 伪目标 3 总结 1 gcc/g 当我们创建一个文件&#xff0c;并向里面写入代码&#xff0c;此时&#xff0c;我们该如何使我们的代码能够运行起来呢&…

Vivado Repository IP Catalog 释疑

Vivado软件自带了一个IP核仓库&#xff0c;可以在IP Catalog界面查看。 在IP目录界面&#xff0c;依次给出了每个IP核的Name(名称)&#xff0c;Interface(接口)&#xff0c;State(状态)&#xff0c;License(许可证)和VLNV&#xff08;标识符&#xff09;。 Interface表示IP核的…

C++指针(五)完结篇

个人主页&#xff1a;PingdiGuo_guo 收录专栏&#xff1a;C干货专栏 前言 相关文章&#xff1a;C指针&#xff08;一&#xff09;、C指针&#xff08;二&#xff09;、C指针&#xff08;三&#xff09;、C指针&#xff08;四&#xff09;万字图文详解&#xff01; 本篇博客是介…

c++0305习题

一、求下面表达式的值 1&#xff0e;0 2&#xff0e;-1 3&#xff0e;1 4&#xff0e;&#xff08;1&#xff09;1 &#xff08;2&#xff09;3.2 &#xff08;3&#xff09;0 &#xff08;4&#xff09;7.0 5.&#xff08;1&#xff09;0&#xff08;2&#xff09;300.005&a…

[力扣 Hot100]Day49 二叉树的最近公共祖先

题目描述 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。 百度百科中最近公共祖先的定义为&#xff1a;“对于有根树 T 的两个节点 p、q&#xff0c;最近公共祖先表示为一个节点 x&#xff0c;满足 x 是 p、q 的祖先且 x 的深度尽可能大&#xff08;一个节点也可以…

服务器与文件内数据的 LENGTH_IN_CHAR 参数不匹配

导入数据库数据的时候出现这个 怎么解决&#xff1a;重建数据库实例 下面是达梦的工具 使用DM数据库配置助手 新建、删除实例 新建实例时的配置需要注意的选项 主要是字符集、大小写、和VARCHAR类型以字符为单位 出现【LENGTH_IN_CHAR 参数不匹配】勾选【VARCHAR类型以字…

NUC980开发板CAN开发笔记

一、内核开启CAN CAN 设置 NUC980 系列带有2个CAN(Controller Area Network), 可以分别独立设置。 请按以下的说明来使能CAN功能. 每个CAN可以单独的开关. CAN0有多组管脚可以选择, 需要一并设置。 使用者也可以设置CAN的唤醒功能。步骤如下&#xff1a; 进入 NUC980-linux-4.…

Linux系统安装及简单操作

目录 一、Linux系统安装 二、Linux系统启动 三、Linux系统本地登录 四、Linux系统操作方式 五、Linux的七种运行级别&#xff08;runlevel&#xff09; 六、shell 七、命令 一、Linux系统安装 场景1&#xff1a;直接通过光盘安装到硬件上&#xff08;方法和Windows安装…

1.初学docker

这是在centos7上的基本操作用法。 一、基本操作 # 安装yum源 yum install -y yum-utils # 配置yum源 yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo # 安装docker yum install -y docker-ce-cli containerd.io docker-buildx-plu…

计算机网络-数据链路层

一、认识以太网 "以太网" 不是⼀种具体的网络&#xff0c;而是一种技术标准; 既包含了数据链路层的内容, 也包含了⼀些物理 层的内容。 例如&#xff1a;规定了网络拓扑结构&#xff0c;访问控制方式&#xff0c;传输速率等; 例如&#xff1a;以太网中的网线必须使用…

mysql的trace追踪SQL工具,进行sql优化

trace是MySQL5.6版本后提供的SQL跟踪工具&#xff0c;通过使用trace可以让我们明白optimizer&#xff08;优化器&#xff09;如何选择执行计划。 注意&#xff1a;开启trace工具会影响mysql性能&#xff0c;所以只适合临时分析sql使用&#xff0c;用完之后请立即关闭。 测试数…

MQ高可用相关设置

文章目录 前言MQ如何保证消息不丢失RabbitMQRocketMQKafkaMQ MQ如何保证顺序消息RabbitMQRocketMQKafka MQ刷盘机制/集群同步RabbitMQRocketMQKafka 广播消息&集群消息RabbitMQRocketMQ MQ集群架构RabbitMQRocketMQKafka 消息重试RabbitMQRockeMqKafka 死信队列RocketMQKaf…

基于springboot实现中小企业财务管理系统项目【项目源码+论文说明】计算机毕业设计

基于springboot实现中小企业财务管理系统演示 摘要 自改革开放一来&#xff0c;我国的经济发展进入到了快速发展时期&#xff0c;大城市的经济水平不断提高&#xff0c;吸引了很多的人不愿千里来大城市奋斗。一个企业的发展离不开相关的规定流程。信息化到来的今天在我们的生活…

计算机网络(基础篇)复习笔记——体系结构/协议基础(持续更新中......)

目录 1 计算机网络基础相关技术Rip 路由更新操作 2 体系结构(OSI 7层, TCP/IP4层)应用层运输层网络层IPv4无分类域间路由选择 CIDRIPV6 数据链路层循环冗余校验CRC协议设备 物理层传输媒体信道复用技术宽带接入技术数据通信 3 网络局域网(以太网Ethernet) 4 通信过程编码:信道极…