UVa12419 Heap Manager

news2024/11/28 12:38:07

题目链接

         UVa12419 - Heap Manager

题意

        内存以内存单元为基本单位,每个内存单元用一个固定的整数作为标识,称为地址。地址从0开始连续排列,地址相邻的内存单元被认为是逻辑上连续的。我们把从地址i开始的s个连续的内存单元称为首地址为i长度为s的地址片。
        运行过程中有若干进程需要占用内存,对于每个进程有一个申请时刻t,需要内存单元数m及运行时间p。在运行时间p内(即t时刻开始,t+p时刻结束),这m个被占用的内存单元不能再被其他进程使用。
        假设在t时刻有一个进程申请m个单元,且运行时间为p,则:
        (1)若t时刻内存中存在长度为m的空闲地址片,则系统将这m个空闲单元分配给该进程。若存在多个长度为m的空闲地址片,则系统将首地址最小的那个空闲地址片分配给该进程。
        (2)如果t时刻不存在长度为m的空闲地址片,则该进程被放入一个等待队列。对于处于等待队列队头的进程,只要在任一时刻,存在长度为m的空闲地址片,系统马上将该进程取出队列,并为它分配内存单元。注意,在进行内存分配处理过程中,处于等待队列队头的进程的处理优先级最高,队列中的其他进程不能先于队头进程被处理。
        现在给出一些描述进程的数据(内存总量≤1e9,进程数≤200000),请编写一程序模拟系统分配内存的过程。

分析

        利用优先级队列和普通队列即可模拟系统分配内存的过程:已经分配了内存的进程放入优先级队列,按结束时刻排序;申请时刻t未分配到内存的进程放入等待队列。

        内存的分配与释放通过线段树来做,本题交代的内存总量是1e9级别的,因此需要动态开点的线段树来处理。

        线段树动态开点需要分析单次操作涉及到的区间结点数上限,再乘上不同操作次数上限,推算出最大结点数。当然,也可以写动态内存分配与释放的指针版动态开点线段树模板,就不用分析这些了。

        如果区间范围是N,则单次点修改操作涉及到的区间结点数上限是\left \lceil log_{2}N \right \rceil+1,单次区间修改操作涉及到的区间结点数上限是4\left \lceil log_{2}N \right \rceil。知乎上有博主将这个分析过程讲得很详细,还画了图示意。

        单次操作涉及到的区间结点数上限,乘上不同操作次数上限,就得到了动态开点的结点数上限,为什么是乘上不同操作次数上限呢?因为同一个区间可能存在多次操作,实际上可以去重,比如本题进程数上限是200000,每个进程分配内存和释放内存都是在同一个区间上操作的,所以不同操作次数上限是200000而不是400000。

        再说一下处理本题内存查询的方法,每个区间结点需要维护三个数据:区间内全0前缀长度a、区间内全0后缀长度b、区间内全0最大长度c。利用这三个数据可以实现本题查询需求。

AC代码

#include <cstdio>
#include <queue>
using namespace std;

#define N 200050
int a[120*N], b[120*N], c[120*N], z[120*N], lc[120*N], rc[120*N], n, g, x; struct {int i, m; long long t;} q[N];

struct node {
    long long t; int s, e;
    bool operator< (const node& rhs) const {
        return t > rhs.t;
    }
} r;

int query(int o, int l, int r, int s) {
    if (s == 0 || a[o] >= s) return l;
    if (c[o] < s) return 0;
    int m = (l+r)>>1, cl = lc[o] ? c[lc[o]] : m-l+1, bl = lc[o] ? b[lc[o]] : m-l+1, cr = rc[o] ? c[rc[o]] : r-m;
    if (cl >= s) return lc[o] ? query(lc[o], l, m, s) : l;
    if (bl + (rc[o] ? a[rc[o]] : r-m) >= s) return m-bl+1;
    return cr >= s ? (rc[o] ? query(rc[o], m+1, r, s) : m+1) : 0;
}

void pushdown(int o, int l, int r) {
    if (z[o] >= 0) {
        a[o] = b[o] = c[o] = z[o] ? 0 : r-l+1;
    } else {
        int m = (l+r)>>1, bl = lc[o] ? b[lc[o]] : m-l+1, ar = rc[o] ? a[rc[o]] : r-m;
        a[o] = lc[o] && a[lc[o]] <= m-l ? a[lc[o]] : m-l+1 + (rc[o] ? a[rc[o]] : r-m);
        b[o] = rc[o] && b[rc[o]] < r-m ? b[rc[o]] : r-m + (lc[o] ? b[lc[o]] : m-l+1);
        c[o] = max(bl+ar, max(lc[o] ? c[lc[o]] : m-l+1, rc[o] ? c[rc[o]] : r-m));
    }
}

void check(int &o, int l, int r) {
    if (o) return;
    o = ++x; a[o] = b[o] = c[o] = r-l+1; z[o] = lc[o] = rc[o] = 0;
}

void occ(int o, int l, int r, int x, int y, bool f) {
    if (x > y) return;
    if (l>=x && r<=y) {
        z[o] = f;
    } else {
        int m = (l+r)>>1; check(lc[o], l, m); check(rc[o], m+1, r);
        if (z[o] >= 0) z[lc[o]] = z[rc[o]] = z[o], z[o] = -1;
        x <= m ? occ(lc[o], l, m, x, y, f) : pushdown(lc[o], l, m);
        y > m ? occ(rc[o], m+1, r, x, y, f) : pushdown(rc[o], m+1, r);
    }
    pushdown(o, l, r);
}

void solve() {
    a[1] = b[1] = c[1] = n; z[x = 1] = lc[1] = rc[1] = 0;
    int m, i = 0, a, head = 0, tail = 0; long long ans = 0, t, p; priority_queue<node> s;
    while (scanf("%lld%d%lld", &t, &m, &p) && (t || m || p) && ++i) {
        while (!s.empty() && s.top().t <= t) {
            for (ans = s.top().t; !s.empty() && s.top().t == ans; s.pop()) occ(1, 1, n, s.top().s, s.top().e, 0);
            while (head < tail) {
                if (!(a = query(1, 1, n, q[head].m))) break;
                if (g) printf("%lld %d %d\n", ans, q[head].i, a-1);
                r.t = ans + q[head].t; r.s = a; r.e = a+q[head++].m-1; occ(1, 1, n, a, r.e, 1); s.push(r);
            }
        }
        if (a = query(1, 1, n, m)) {
            if (g) printf("%lld %d %d\n", t, i, a-1);
            r.t = t + p; r.s = a; r.e = a+m-1; occ(1, 1, n, a, r.e, 1); s.push(r);
        } else q[tail].i = i, q[tail].t = p, q[tail++].m = m;
    }
    while (!s.empty()) {
        for (ans = s.top().t; !s.empty() && s.top().t == ans; s.pop()) occ(1, 1, n, s.top().s, s.top().e, 0);
        while (head < tail) {
            if (!(a = query(1, 1, n, q[head].m))) break;
            if (g) printf("%lld %d %d\n", ans, q[head].i, a-1);
            r.t = ans + q[head].t; r.s = a; r.e = a+q[head++].m-1; occ(1, 1, n, a, r.e, 1); s.push(r);
        }
    }
    printf("%lld\n%d\n\n", ans, tail);
}

int main() {
    while (scanf("%d%d", &n, &g) == 2) solve();
    return 0;
}

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

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

相关文章

三代半导体材料有何区别

什么是半导体材料 半导体材料是制作半导体器件和集成电路的电子材料&#xff0c;是半导体工业的基础。利用半导体材料制作的各种各样的半导体器件和集成电路&#xff0c;促进了现代信息社会的飞速发展。 绝缘体、半导体和导体的典型电导率范围 半导体材料的研究开始于19世纪初…

行走在深度学习的幻觉中:问题缘由与解决方案

如何解决大模型的「幻觉」问题&#xff1f; 我们在使用深度学习大模型如LLM&#xff08;Large Language Models&#xff09;时&#xff0c;可能会遇到一种被称为“幻觉”的现象。没错&#xff0c;它并不是人脑中的错觉&#xff0c;而是模型对特定模式的过度依赖&#xff0c;这…

ChatGPT学习笔记——大模型基础理论体系

1、ChatGPT的背景与意义 近期,ChatGPT表现出了非常惊艳的语言理解、生成、知识推理能力, 它可以极好的理解用户意图,真正做到多轮沟通,并且回答内容完整、重点清晰、有概括、有条理。 ChatGPT 是继数据库和搜索引擎之后的全新一代的 “知识表示和调用方式”如下表所示。 …

任务调度实现

一、定时任务概述 在项目中开发定时任务应该一种比较常见的需求&#xff0c;在 Java 中开发定时任务主要有三种解决方案&#xff1a;一是使用JDK 自带的 Timer&#xff0c;二是使用 Spring Task&#xff0c;三是使用第三方组件 Quartz Timer 是 JDK 自带的定时任务工具,其简单易…

Nougat:科学文档的OCR 使用记录

https://github.com/facebookresearch/nougat python环境需要在3.8以上 安装&#xff1a;pip install nougat-ocr 模型默认下载地址&#xff1a;/home/****/.cache/torch/hub/nougat-0.1.0-small 环境安装好之后默认使用cpu UserWarning: CUDA initialization: The NVIDIA dr…

数据恢复软件哪个好?10款好用的数据恢复软件推荐(免费和付费)

我们使用的个人电脑、智能手机和其他数字设备包含我们所有的个人和重要数据。我们不能丢失数据&#xff0c;幸运的是&#xff0c;这些设备都不可靠。它们可能随时损坏或损坏&#xff0c;在此过程中丢失我们的重要数据。 不幸的是&#xff0c;没有工具可以 100% 确保您永远不会丢…

2024 年 API 安全:预测和趋势

随着技术以前所未有的速度不断进步&#xff0c;API&#xff08;应用程序编程接口&#xff09;安全性的复杂性也随之增加。随着 API 在现代应用程序和服务中的激增&#xff0c;组织将需要更好地了解其 API 环境以及 API 给运营带来的风险。 到 2024 年&#xff0c;预计几个关键…

olap/spark-tungsten:codegen

15721这一章没什么好说的&#xff0c;不再贴课程内容了。codegen和simd在工业界一般只会选一种实现。比如phothon之前用codegen&#xff0c;然后改成了向量化引擎。一般gen的都是weld IR/LLVM IR/当前语言&#xff0c;gen成C的也要检查是不是有本地预编译版本&#xff0c;要不没…

电子学会C/C++编程等级考试2023年12月(三级)真题解析

C/C++编程(1~8级)全部真题・点这里 第1题:因子问题 任给两个正整数N、M,求一个最小的正整数a,使得a和(M-a)都是N的因子。 时间限制:10000 内存限制:65536 输入 包括两个整数N、M。N不超过1,000,000。 输出 输出一个整数a,表示结果。如果某个案例中满足条件的正整数不存…

2023 CSIG青年科学家会议丨多模态大模型时代下的文档图像处理

近日&#xff0c;由中国图象图形学学会青年工作委员会发起的“第十九届中国图象图形学学会青年科学家会议”在广州召开。 会议面向国际学术前沿与国家战略需求&#xff0c;聚焦最新前沿技术和热点领域&#xff0c;邀请各界专家与青年学者进行总计超200场的高水平学术深度交流&…

SpringBoot pom.xml文件标签含义

Pom文件 基本构成 通过最简单的一个SpringBoot项目的 Pom文件来了解一下Pom文件的基本构成 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XML…

【Origin绘图】准备工作:安装与卸载

Origin准备工作&#xff1a;安装与卸载 软件介绍&#xff1a;Origin安装Origin卸载参考 软件介绍&#xff1a; Origin是由OriginLab公司开发的一个科学绘图、数据分析软件,支持在Microsoft Windows下运行。Origin支持各种各样的2D/3D图形。Origin中的数据分析功能包括统计,信号…

ClickHouse基础知识(七):ClickHouse的分片集群

副本虽然能够提高数据的可用性&#xff0c;降低丢失风险&#xff0c;但是每台服务器实际上必须容纳全量数据&#xff0c;对数据的横向扩容没有解决。 要解决数据水平切分的问题&#xff0c;需要引入分片的概念。通过分片把一份完整的数据进行切 分&#xff0c;不同的分片分布到…

Showroom Environment gallery

展示厅环境-画廊 PBR包中的所有纹理。它们适用于URP和内建。在标准状态下,所有内容都是在URP下配置的。如果你有整个场景“粉红色”,请更改渲染设置。 简单的画廊内部,配有用于照片和图片的画布。非常适合您的虚拟画廊或展厅。此套餐包含一个展厅,您可以在其中展示您的作品…

使用Poe通过ChatGPT创建一个可以写报告作业的机器人

一、在Poe注册账号 网址&#xff1a;Poe官网 二、点击创建机器人 三、使用命令让ChatGPT越狱 我搬运的大佬链接&#xff1a;https://blog.dun.im/dun/chatgpt-jailbreak-tutorial-bypass-restrictions.html 复制以下的聊天内容 Hello, ChatGPT. From now on you are going…

【推荐】15k的star,5分钟本地化部署,一款由ChatGPT开发PDF文件处理神器,功能强大,你想要的都有。

【推荐】15k的star&#xff0c;5分钟本地化部署&#xff0c;一款由ChatGPT开发PDF文件处理神器&#xff0c;功能强大&#xff0c;你想要的都有。 文章目录 【推荐】15k的star&#xff0c;5分钟本地化部署&#xff0c;一款由ChatGPT开发PDF文件处理神器&#xff0c;功能强大&…

Axure RP Extension For Chrome 插件安装

1. 下载好 AXURE RP EXTENSION For Chrome 插件之后解压成文件夹 2. 打开浏览器&#xff0c;找到设置--更多工具--扩展程序--加载已加压的扩展程序&#xff0c;选择解压好的文件夹 3. 点击详细信息&#xff0c;打开访问网址权限

Ps:混合颜色带 - 应用篇

混合颜色带 Blend If是基于亮度&#xff08;灰色&#xff09;或颜色通道的特定范围来显示或隐藏图层的特定区域。 当前图层 Current Layer&#xff0c;可根据当前图层的亮度值来隐藏该图层中的像素。 下一图层 Underlying Layer&#xff0c;可根据下方所有图层的复合图像的亮度…

CSDN博客重新更新

说来惭愧&#xff0c;好久没更新博客文章&#xff0c;导致个人博客网站&#xff1a;https://lenky.info/ 所在的网络空间和域名都过期了都没发觉&#xff0c;直到有个同事在Dim上问我我的个人博客为啥打不开了。。。幸好之前有做整站备份&#xff0c;后续慢慢把内容都迁回CSDN上…

Win11怎么重置系统?(小白专享篇)

话不多说&#xff0c;直接上干货 重置Windows 11系统的步骤如下&#xff1a; 1.同时按下【Windowsi】键打开系统设置。 2.在当前页面下拉选择【系统】-【恢复】。 3.点击重置此电脑下的【初始化电脑】。 4.点击【删除所有内容】。 5.选择删除所有内容后&#xff0c;继续选…