第三题 流水线

提交文件: 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. c# .NET 高级编程 高并发必备技巧 - 锁

    锁 最为常见的应用就是 高并发的情况下,库存的控制.本次只做简单的单机锁介绍. 直接看代码: 每请求一次库存-1. 假如库存1000,在1000个人请求之后,库存将变为0. public int Re ...

  2. 《Kali渗透基础》13. 无线渗透(三)

    @ 目录 1:无线通信过程 1.1:Open 认证 1.2:PSK 认证 1.3:关联请求 2:加密 2.1:Open 无加密网络 2.2:WEP 加密系统 2.3:WPA 安全系统 2.3.1:WP ...

  3. Hadoop单击模式运行wordcount例子

    1.进入Hadoop安装目录 cd /zwy/soft/hadoop-2.7.1 2.创建文件夹input mkdir input 3.写一段文字到文件file.txt echo "hell ...

  4. CodeIgniter 视图篇

    什么是视图 简单来说,一个视图其实就是一个 Web 页面,或者页面的一部分,像页头.页脚.侧边栏等. 实际上,视图可以很灵活的嵌在另一个视图里,然后这个视图再嵌在另一个视图里,等等, 如果你想使用这种 ...

  5. 后端常用的Linux命令大全,建议收藏

    引言 作为一名后端工程师,使用终端是一种常见的做法,也是你应该学习的技能.许多命令和实用程序可以帮助你在使用 Linux 时更有效地完成任务. 基本 Linux 命令 如果你想使用 Linux 操作系 ...

  6. 「joisc 2019 - d2t2」ふたつの料理 Two Dishes

    [link.](E - ふたつの料理 (Two Dishes) (atcoder.jp) 我要放假 神仙题. 首先可以把两根轴拉成平面(which is a common trick),把决策的过程看 ...

  7. 小札 Maximum Weight Closure of a Graph

    1. Introduction    Define a closure of a directed graph \(G=(V,E)\) as an induced set of vertexes of ...

  8. ArcGIS将遥感影像的0值设置为NoData

      本文介绍在ArcMap软件中,将栅格图层中的0值或其他指定数值作为NoData值的方法.   在处理栅格图像时,有时会发现如下图所示的情况--我们对某一个区域的栅格数据进行分类着色后,其周边区域( ...

  9. Linux平台Oracle 23c单实例 安装部署配置 快速参考

    转眼间已经2023年,再有一周就要过年了,在这里先给大家拜个早年,祝大家新的一年万事顺利. Oracle如今版本号也和年份挂钩,在前段时间的OCW上也宣布发布了beta版本的23c,因为23c是继19 ...

  10. PostgreSQL学习笔记-3.基础知识:CROSS、INNER、LEFT OUTER、RIGHT OUTER、FULL OUTER、UNION

    PostgreSQL JOIN 子句用于把来自两个或多个表的行结合起来,基于这些表之间的共同字段. 在 PostgreSQL 中,JOIN 有五种连接类型: CROSS JOIN :交叉连接INNER ...