第三题 流水线

提交文件: line.cpp

输入文件: line.in

输出文件: line.out

时间空间限制: 2 秒, 256 MB

在计算机组成原理这门课中,小明的老师布置了实现 CPU 流水线的作业。小明打算设计出一个效率最高的流水线。简单来说,流水线就是 将 CPU 分成若干个任务模块,而一个模块又可以继续划分成更小的模块,小模块可以划分成更小的小小模块……根据常识我们知道把一个任务划分后,每一个部分的代价会变少,但是可能会产生额外的代价。所以小明希望你帮助他解决这个问题。

我们可以用一棵以 1 为根的有根树来描述模块之间的关系,每个节点是一个模块,每个节点的点权对应着该模块的时间代价。每一个非叶子节点可以划分成该节点的儿子节点对应的模块。

每个模块都有一定的时间代价,而流水线最后的效率我们可以用划分的模块数乘上模块中时间代价最大的一个来表示,时间代价越小,流水线的效率越高。也就是说,假如小明最后把 CPU 划分为了 m 个模块,每个模块的代价为 \(w_1, w_2, \cdots , w_m\),则总代价为 \(m \cdot max(w_1, w_2,\cdots, w_m)\)。另外,我们认为根节点对应的模块不往下划分模块也是一种合法的方案。

请你帮小明找到效率最高的流水线设计方案吧

输入格式

第一行一个正整数 \(n\),表示模块对应有根树的节点个数。

第二行 \(n\) 个整数,表示 \(n\) 个模块的时间代价 \(w_i\)。

第三行 \(n − 1\) 个数 \(f_i(2 ≤ i ≤ n)\),表示节点 \(2,\cdots , n\) 在有根树中的父节点。保证给出的是一棵以 \(1\) 为根的树。

输出格式

一个整数 T,表示最小的时间代价。

样例数据

line.in line.out

5

10 7 3 3 2

1 1 2 2

9

样例解释

样例中将模块 1 拆分为模块 2 和模块 3,再将模块 2 拆分为模块 4 和模块 5,代价为 3 · 3 = 9。

数据范围

对于所有测试点,\(1 ≤ n ≤ 10^5,0 ≤ w_i ≤ 10^9,w_i ≤ w_{f_i}\)。

测试点 \(n ≤\) \(w_i ≤\)
1 ∼ 2 \(20\) \(10^9\)
3 ∼ 4 \(500\) \(10^9\)
5 ∼ 7 \(10^5\) \(100\)
8 ∼ 10 \(10^5\) \(10^9\)

两个数相乘,我们可以尝试枚举一个,另一个用贪心求。

w数组明显可以离散化,所以把它离散化。我们有两个思路,要不求只有\(x\)个数时所有数最大值最小是多少,要不求最大值\(\le x\)的时候最少有多少个数。第一个思路走不下去,考虑第二个思路。

离散化后,我们枚举最大值,例如现在是小于等于\(x\)的最少数量,那么很容易发现,应该是如果还存在大于\(x\)的点,那么就要把他给拆了。由于\(w_i ≤ w_{f_i}\),所以我们把所有\(w\)从大到小枚举,每一次看现在还存在的点里面有没有大于\(w_i\)的,如果有就拆了,拆完后用最大值乘上存在的点的数量。我们具体可以使用堆实现,如果堆中的最大值大于\(w_i\),那么就把它拆开,拆出来的点放入堆中,可以达到\(O(nlogn)\)的复杂度。

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int lsh[N],w[N],hd[N],fth,n;
long long ans=1e18;
struct edge{
int v,nxt;
}e[N];
struct node{
int x,w;
bool operator<(const node&n)const{
return w<n.w;
}
};
priority_queue<node>q;
void add_edge(int u,int v)
{
e[v]=(edge){v,hd[u]};
hd[u]=v;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",w+i),lsh[i]=w[i];
for(int i=2;i<=n;i++)
scanf("%d",&fth),add_edge(fth,i);
sort(lsh+1,lsh+n+1);
for(int i=1;i<=n;i++)
w[i]=lower_bound(lsh+1,lsh+n+1,w[i])-lsh;
q.push((node){1,w[1]});
for(int i=n;i>=1;i--)//枚举点权
{
while(q.top().w>i&&hd[q.top().x])
{
for(int i=hd[q.top().x];i;i=e[i].nxt)
q.push((node){e[i].v,w[e[i].v]});
q.pop();
}
if(q.top().w<=i)
ans=min(ans,1LL*lsh[i]*(long long)q.size());
}
printf("%lld",ans);
return 0;
}

[GDOIpj221C] 流水线的更多相关文章

  1. CI-持续集成(1)-软件工业“流水线”概述

    CI-持续集成(1)-软件工业“流水线”概述 1   概述 持续集成(Continuous integration)是一种软件开发实践,即团队开发成员经常集成它们的工作,通过每个成员每天至少集成一次, ...

  2. 【GoLang】golang 的精髓--流水线,对现实世界的完美模拟

    直接上代码: package main import ( "fmt" "runtime" "strconv" "sync" ...

  3. android so调试时遇到的坑 - arm流水线

    直接看下面这段ARM汇编: 此时运行到的代码为ADD R3,PC 此时看一下寄存器窗口的值: 按理来说执行完ADD R3,PC后的效果应该是R3=R3+PC ,R3=40A1D5C8 但是我们可以执行 ...

  4. 【转载】关于OpenGL的图形流水线

    本文转载自 http://blog.csdn.net/racehorse/article/details/6593719 GLSL教程 这是一些列来自lighthouse3d的GLSL教程,非常适合入 ...

  5. .Net中的并行编程-5.流水线模型实战

    自己在Excel整理了很多想写的话题,但苦于最近比较忙(其实这是借口).... 上篇文章<.Net中的并行编程-4.实现高性能异步队列>介绍了异步队列的实现,本篇文章介绍我实际工作者遇到了 ...

  6. Intel系列CPU的流水线技术的发展

    Intel系列CPU的流水线技术的发展 CPU(Central processing Unit),又称“微处理器(Microprocessor)”,是现代计算机的核心部件.对于PC而言,CPU的规格与 ...

  7. Verilog学习笔记设计和验证篇(一)...............总线和流水线

    总线 总线是运算部件之间数据流通的公共通道.在硬线逻辑构成的运算电路中只要电路的规模允许可以比较自由的确定总线的位宽,从而大大的提高数据流通的速度.各个运算部件和数据寄存器组可以通过带有控制端的三态门 ...

  8. ARM流水线关键技术分析与代码优化

    引 言    流水线技术通 过多个功能部件并行工作来缩短程序执行时间,提高处理器核的效率和吞吐率,从而成为微处理器设计中最为重要的技术之一.ARM7处理器核使用了典型三级流 水线的冯·诺伊曼结构,AR ...

  9. TMS320C54x系列DSP的CPU与外设——第8章 流水线

    第8章 流水线 本章描述了TMS320C54x DSP流水线的操作,列出了对不同寄存器操作时的流水线延迟周期.(对应英语原文第7章) 8.1 流水线操作 TMS320C54x DSP有一个6段的指令流 ...

  10. Redis附加功能之Redis流水线pipeline

    流水线功能的目的:通过减少客户端与服务器之间的通信次数来提高程序的执行效率. 一.通信 在一般情况下, 用户每执行一个 Redis 命令,客户端与服务器都需要进行一次通信:客户端会将命令请求发送给服务 ...

随机推荐

  1. 在Jupyter中使用AI写代码,如有神助,太惊艳了

    昨晚看到一个可以在JupyterLab中使用的AI代码辅助工具jupyter-ai,它的交互确实非常棒,可以直接聊天,也可以就笔记中的代码提问,最出彩的是生成笔记功能,还是蛮惊艳的. 这里就极简介绍一 ...

  2. 千万级数据的表,我把慢sql优化后性能提升30倍!

    分享技术,用心生活 背景:系统中有一个统计页面加载特别慢,前端设置的40s超时时间都加载不出来数据,因为是个统计页面,基本上一猜就知道是mysql的语句有问题,遗留了很久没有解决,正好趁不忙的时候,下 ...

  3. 算术逻辑单元的实现(ALU)

    一.实验目的 掌握Vivado集成开发环境 掌握Verilog语言基本知识. 掌握并理解算术逻辑单元ALU的原理和设计 二.实验预习 1.ALU(算术逻辑单元)的16种运算的编码 三.模块接口设计 A ...

  4. iOS添加图片

    添加一个按钮 将图片添加到

  5. Conda 命令深入指南

    Conda 命令深入指南 Conda 是一个功能强大的包管理系统,允许您为不同的项目创建和管理隔离的环境,从而更轻松地处理不同的依赖项集. 安装 可以按照 Conda 官方网站 (https://co ...

  6. Github的一个奇技淫巧

    背景 前段时间给 VictoriaLogs 提交了一个 PR: https://github.com/VictoriaMetrics/VictoriaMetrics/pull/4934 本来一切都很顺 ...

  7. 记录一次gcc的编译

    在deepin23上编译gcc13.2 deepin20素以软件版本过老被人诟病,换成最新的deepin23之后情况大有好转,但是gcc版本为11.2,鄙人对此仍有意见,所以特意研究了如何编译一份较新 ...

  8. linux常见命令(五)

    用于文本内容处理的相关命令 sort uniq cut comm diff sort:对文件中数据进行排序,并将结果显示在标准输出上 命令语法:sort [选项] [文件] 选项 选项含义 -m 如果 ...

  9. linux文件、目录权限和所有者

    文件.目录权限和所有者 简介:用户对一个文件或目录具有访问权限,这些访问权限决定了谁能访问,以及如何范围这些文件和目录.通过设置权限可以限制或允许以下三种用户访问: 文件的用户所有者(属主) 文件的组 ...

  10. client-go实战之九:手写一个kubernetes的controller

    欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇概览 本文是<client-go实战> ...