做题随笔:P5763

news/2025/2/12 18:07:15/文章来源:https://www.cnblogs.com/Tenil/p/18711971

Solution

直接模拟的各种方法可以参考其他题解,复杂度大概为 \(O(k^2)\),本篇不详讲,只做引入。蒟蒻做题时想到了,但是一看 \(k\leq 9998\),感觉有点不妥,万一有个常数直接 T 掉,于是用一天调了一个 \(O(k\log^2 k)\)(好像是,已经分析不懂了),详见下文。

题意

原题链接

\(N\) 个连续编号的单元,\(k\) 条指令,每条指令占用 \(M_i\) 个编号尽可能小的连续单元 \(P_i\) 时间,在 \(T_i\) 时刻执行。若 \(T_i\) 时刻无法执行则进入等待队列,队头指令一旦可以执行立刻执行(除 \(k\leq 9998\) 外,其他数据均小于 \(1 \times 10^9\))。

求所有指令完成的时刻和进入过等待序列的指令数。

有几个细节:

  1. 等待队列的指令优先于输入指令执行;
  2. 占用时间是(开始时间 \(t_i\)):\([t_i,t_i+P_i)\)
  3. 最终要求的是完成时间,相当于 2 中的 \(t_i+P_i\)
  4. 时间可以从 \(0\) 开始。

分析 & 实现

1. 直接模拟

可以发现,题目的描述都是清晰的流程,且所求正是按流程操作过程中可以得到的值,而且数据范围可接受,自然可以想到直接模拟:一个 \(\text{vector}\) 当内存条,每次取最左的可行段拆开,更新时间标记;一个 \(\text{queue}\) 作等待队列,直接按照流程操作即可。

2. 堆优化

依据 1 的大体思路,我们现在有一个存 \((l_i,r_i,st_i)\)\(\text{vector}\) 当内存条(\(st_i\) 即内存释放时间),一个存 \((M_i,P_i)\)\(\text{queue}\) 作等待队列,现在考虑怎么优化。

第一个问题:如何在 \(T_i\) 满足条件的同时,更低代价最小化 \(l\)

先不考虑合并问题,思考如何在 \(T_i\) 满足条件的同时,最小化连续单元左端点编号 \(l\)。由于我们需要改点,理应需要能够动态维护、随机访问。如果做双关键字排序的话,其实也可以干:众所周知,\(\text{STL set}\) 可以满足动态维护和随机访问的要求,而且其内置的二分查找可加速查询;或者手写一个二叉堆亦可满足需求。但是这比较标新立异,容易出错,蒟蒻这里用的是比较常规的分离参数。

先建一个内存条依据 \(T_i\) 排序的小根堆,筛选对应满足 \(T_i\) 条件的当前内存段,将其时间标记统一更新为 \(-\text{INF}\) 后(由于 \(T_i\) 单调递增,现在已经满足的之后一定也满足),转移到一个依据 \(l_i\) 排序的小根堆中,其堆顶就是满足 \(T_i\) 条件且 \(l\) 最小的一个。这样做相当于消去了 \(T_i\) 后继续比较,自然可以求得 \(l\) 最小段。需要使用时,取第二个堆的堆顶(假设够长),用的一段更新时间标记后丢回第一个堆,省的一段留在原堆。这样做,一段区间不会被过多次数地进行排序,从而降低了复杂度,大体 \(O(n\log n)\)

第二个问题:如何合并可用段

一个显然的结论是:连续的两段内存,左边一段的 \(r\) 等于右边一段的 \(l\) 减一。所以直接根据这个性质在上文所述的第二个堆中合并即可。但是这样其实是不行的,问题又回到了随机访问。所以考虑把 \(\text{STL priority\_queue}\) 换成 \(\text{STL vector}\),每次新元素加入时,\(\text{sort}\) 一下,或者直接二分插入,依然能够维护单调性。

当要占用单元时,先把整个 \(\text{STL vector}\) 扫一遍,合并相邻内存段,再找到第一个长度不小于 \(M_i\) 的内存段,直接用它。这里还可以再跑一个二分查找,不过本蒟蒻就直接扫了。

第三个问题:如何解决等待队列

这个其实就比较简单了,每次先考虑等待队列中的元素即可。但是需要注意一点:等待队列中的指令执行不止可能在新指令执行前,还可能是任何内存释放时,所以说需要记录一下所有使用中的内存的释放时间,考虑开一个时间队列。由于等待队列中的指令是一有机会就执行,所以说应该用小根堆存。注意:\(\text{STL priority\_queue}\) 默认大根堆!

大方向上就是这些,其他的一些细节问题在代码里。

Code

#include <iostream>
#include <cstdio>
#include <cctype>
#include <queue>
#include <vector>
#include <algorithm>using namespace std;typedef long long ll;inline ll fr() {ll x=0,f=1;char c=getchar();while(!isdigit(c)) {if(c=='-') f=-1;c=getchar();}while(isdigit(c)) {x=(x<<1)+(x<<3)+(c^48);c=getchar();}return x*f;
}struct qus{ll l,r,st;qus (ll _l,ll _r,ll _st) {l=_l,r=_r,st=_st;}bool operator <(const qus &q1) const &{return q1.st<st;//注意:这样的小于其实返回的是大于的结果,但是对上大根堆就正好}
};	bool cmp(qus q1,qus q2) {return q1.l<q2.l;//这个才是正常的
}struct wait{ll m,p;wait (ll _m,ll _p) {m=_m,p=_p;}
};const int maxn=1e4+100;
ll n,anst,ansn;
priority_queue<qus> Q;//上文“第一个堆”
priority_queue<int,vector<int>,greater<int> > tq;//时间队列,小根堆
deque<wait> q;//等待队列
vector<qus> v;//上文“第二个堆”int main() {n=fr();Q.push(qus(1,n,-1145141919810));ll t=fr(),m=fr(),p=fr(),tt=0,mm=0,pp=0;//tt,mm,pp表示本次使用的t,m,p的值bool flag=true;while(m||!q.empty()) {//正常输入不可能占用0个单元bool wt=false;//是否使用等待队列元素if(!q.empty()&&!tq.empty()) {if(tq.top()<=t||!m) {tt=tq.top();mm=q.front().m;pp=q.front().p;q.pop_front();wt=true;}else {tt=t;mm=m;pp=p;}}else {tt=t;mm=m;pp=p;}
//上文“第一个问题”if(!Q.empty()) {while(Q.top().st<tt) {v.push_back(qus(Q.top().l,Q.top().r,-1145141919810));Q.pop();if(Q.empty()) break;}}
//上文“第二个问题”sort(v.begin(),v.end(),cmp);	int lim=(int)v.size();for(register int i = 0; i < lim; i++) {if(v[i].l>v[i].r) {//非法判断v.erase(v.begin()+i);lim--;i--;//erase的时候删除点后面的都会减一,如果i++了反而跳过一个}}for(register int i = 1; i < lim; i++) {if(v[i-1].r==v[i].l-1) {v[i].l=v[i-1].l;v.erase(v.begin()+i-1);lim--;i--;}}bool vis=false;for(register int i = 0; i < (int)v.size(); i++) {qus x=v[i];if(x.r-x.l+1>=mm) {Q.push(qus(x.l,x.l+mm-1,tt+pp-1));//这里减一,所以上面“第一个问题”处不能取等v[i].l+=mm;tq.push(tt+pp);//第三个问题:时间队列赋值的时候取的等,所以这里不能减vis=true;break;}}if(!vis) {if(!wt) {q.push_back(wait(mm,pp));ansn++;}else {q.push_front(wait(mm,pp));//等待队列中的不可行,要扔回去tq.pop();}}if(!wt) {if(m) {if(!tq.empty()) {while(tq.top()<t) {tq.pop();if(tq.empty()) break;//小于当前时间的一定不行了(可行的话之前就用了),剪掉}}t=fr(),m=fr(),p=fr();}}}while(!Q.empty()) {anst=Q.top().st;Q.pop();//小根堆,最后一个最大}printf("%lld\n%lld\n",anst+1,ansn);//上面减了一,这里要加回来return 0;
}

闲话

如果觉得有用,点个赞吧!(调了一上午加一中午,写了一下午,蒟蒻尽力了)

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

XXE

XXE漏洞产生原因 XXE漏洞:XML外部实体注入漏洞;应用程序解析XML输入时,没有对上传的XML文件内容进行过滤,没有禁止外部实体的加载,导致可以加载恶意外部文件,造成文件读取、命令执行、内网端口扫描、DOS攻击等。 XXE与HTML XML是可扩展标记语言、重点在传输数据和存储数据…

官媒报纸下载器 | 快速下载电子版报纸

报纸下载器是一款可以快速下载电子版报纸的应用,无需安装双击即可使用。 它支持人民日报、农民日报、经济日报、中国证券报、工人日报、科技日报等多家官方报纸的在线下载。 可选择报纸并设置日期,点击下载按钮后,报纸将以PDF格式下载到本地。 下载进度和版面信息会在底部状…

反序列化

序列化与反序列化 序列化:把一个对象类型的数据转换成字符串(字节流)进行传输,把某个对象系列化成JSON格式或XML格式或者其他序列化格式的字符串过程称为序列化。 反序列化:将字节流或字符串转换为原始的数据结构或对象。 shiro反序列化 shiro-550:shiro < 1.2.5 主要是…

RockyLinux操作系统

RockyLinux操作系统 1 系统介绍 2020 年 12 月 8 日,Red Hat 宣布他们将停止开发 CentOS,CentOS 一直是 Red Hat Enterprise Linux 的生产就绪下游版本,转而支持该作系统的较新的上游开发变体,称为“CentOS Stream”。作为回应,CentOS 的最初创办人 Gregory Kurtzer 在 Ce…

域名解析—互联网世界的导航系统

在互联网的世界里,每个网站都像一座“城市”,而用户要找到这些“城市”,必须依赖一套精准的导航系统——这就是域名解析。无论是浏览网页、发送邮件,还是使用移动应用,域名解析都在背后默默支撑着用户的每一次访问。本文将深入浅出地解析域名解析的原理、流程及其在互联网…

算法备案办理经验分享

算法备案实际办理经验,包含流程、材料和注意事项作为一名算法备案代办服务人员,之前又有一批客户通过了算法备案。趁着最近闲下来,今天就跟大伙分享下我做算法备案的经验,如有任何疑问,欢迎大家直接提问。一、算法备案流程 1.注册与主体信息提交 首先得登录互联网信息服务…

基于Ollama+DeepSeek+AnythingLLM轻松投喂打造本地大模型知识库.250212

第一步,下载开源的[AI]应用程序AnythingLLM 去官网Download AnythingLLM for Desktop下载并安装即可。 第二步,下载Ollama并获取DeepSeek LLM) 为了使用DeepSeek我们需要先下载Ollama并获取DeepSeek。 1、打开 Ollama 的官网http://ollama.com,在官网找到 “Download”,点击…

LLM与对话UI

部署后的LLM只能在终端使用的话不怎么友好,我们可以通过现有的工具接入到友好的聊天UI中。 chatBox 这是一个本地应用程序(现在支持web),可以通过配置,访问本地或者远端的大语言模型。 一、安装 在官网下载对应的安装包,安装应用。 二、配置模型 1、OPENAI API:需要提供…

智慧消防网页低延迟播放RTSP视频流,低至300毫秒,25路不卡顿

在城市化进程加速的今天,消防安全已成为社会治理的核心课题。智慧消防通过物联网、人工智能、大数据等技术,构建实时感知、智能预警、快速响应的防控体系,但其核心环节——视频监控的实时性与可靠性,却长期面临技术瓶颈。传统消防监控系统依赖服务器转码方案,导致延迟高、…

关于git rebase中的一些问题:Git报错“no branch, rebasing master”

冲突原理:由于远程仓库和本地的commit有冲突,Git无法自动解决冲突时,会切换到一个匿名分支,然后使用git branch -a命令会发现变为如下图的样子:手动解决完冲突后,先执行git add -A(很重要),然后执行git rebase --continue, 如果没有任何需要解决的冲突了,git会自动把匿…

工程大数据平台

由于无人驾驶系统开发需要长期迭代优化,其过程需要的大量的路试数据支撑,经纬恒润针对无人驾驶系统的持续运营和持续迭代优化的需求,开发并在云端部署了车路云大数据工程平台,依托5G网络,具有远程数据采集、压缩、传输、解析、回放、与算法开发工具无缝对接等功能,可服务…