一个裸的优先级队列(最大堆)题,但也有其他普通队列的做法。这道题我做了两天,结果发现是输入输出太过频繁,一直只能A掉55%的数据,其他都是TLE,如果将输入输出的数据放入缓存区,然后满区输出,可以将IO时间消耗降到很低。

任务调度(Schedule)


描述

某高性能计算集群(HPC cluster)采用的任务调度器与众不同。为简化起见,假定该集群不支持多任务同时执行,故同一时刻只有单个任务处于执行状态。初始状态下,每个任务都由称作优先级数的一个整数指定优先级,该数值越小优先级越高若优先级数相等,则任务名ASCII字典顺序低者优先。此后,CPU等资源总是被优先级数最小的任务占用;每一任务计算完毕,再选取优先级数最小下一任务。不过,这里的任务在计算结束后通常并不立即退出,而是将优先级数加倍(加倍计算所需的时间可以忽略)并继续参与调度;只有在优先级数不小于2^32时,才真正退出

你的任务是,根据初始优先级设置,按照上述调度原则,预测一批计算任务的执行序列。

输入

第一行为以空格分隔的两个整数n和m,n为初始时的任务总数,m为所预测的任务执行序列长度,每行末尾有一个换行符

以下n行分别包含一个整数和一个由不超过8个小写字母和数字组成的字符串。前者为任务的初始优先级数,后者为任务名。数字和字符串之间以空格分隔

输出

最多m行,各含一个字符串。按执行次序分别给出执行序列中前m个任务的名称,若执行序列少于m,那么输出调度器的任务处理完毕前的所有任务即可。

Example

Input

3 3
1 hello
2 world
10 test

Output

hello
hello
world

限制

0 ≤ n ≤ 4,000,000

0 ≤ m ≤ 2,000,000

0 < 每个任务的初始优先级 < 2^32

不会有重名的任务

时间:2 sec

内存:512 MB


  解题思路:

    首先是优先级队列(最大堆),关于该问题的讨论,可以参见我第一篇文章 算法手记 之 数据结构(堆)(POJ 2051)

    建堆算法和插入算法在听过邓俊辉老师的MOOC后进行了优化,批量建堆操作可以将时间度综合效率经过下滤优化至O(N),相对第一次接触堆的时候有了较大的提高,手写堆得代码也可以因此变得更为简洁。详细算法参加下面的代码。

    其次是关于快速输入输出(FastIO),我在这里用结构体进行封装,创建对象IO时可以完成构造函数的操作,包括stdin和stdout两个流向,一个是最大400万次输入,一个是最大200万次输出,相信这样可以将输入输出此时降至十位甚至个位数,将输入输出对时间的消耗降至极低的水平。

    简单介绍这里使用的一个设置文件缓存区的函数和另一个相似函数:

    设置文件缓冲区函数
      void setbuf(FILE *stream,char *buf);

      void setvbuf(FILE *stream,char *buf,int type,unsigned size);
      这两个函数将使得打开文件后,用户可建立自己的文件缓冲区,而不使用fopen()函数打开文件设定的默认缓冲区。

      对于setbuf()函数,buf指出缓冲区长度,由stdio.h中定义的宏BUFSIZE的值决定,缺省为512字节。当buf为空时,setbuf函数将使的文件I/O不带缓冲。

      对setvbuf函数,则由malloc函数来分配缓冲区,参数size指明了缓冲区的长度。

    type则表示了缓冲的类型,其值可以取如下值:

      _IOFBF 文件全部缓冲,即缓冲区装满后,才能对文件读写
      _IOLBF 文件行缓冲,即缓冲区接收到一个换行符时,才能对文件读写

      _IONBF 文件不缓冲,此时忽略buf,size的值,直接读写文件,不再经过文件缓冲区缓冲

  代码的写法模仿了一篇博客,在此表示感谢:terence-yang

  具体代码如下:

  

 //优先级队列+快速输入输出(批量)
//Time: 1508Ms Memory: 109488K(No.20)
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std; #define MAX 4000005
#define LCHILD(x) ((x)<<1)
#define RCHILD(x) (((x)<<1) + 1)
#define PRIOR(A,x,y) (A[x]>A[y]?(x):(y)) int n, m;
const long long INF = (long long) << ; //优先级数上限
const int SIZE = << ; //缓存区大小 /*快速输入输出缓存区设置*/
struct FastIO {
char inbuf[SIZE];
char outbuf[SIZE];
FastIO() {
setvbuf(stdin,inbuf,_IOFBF,SIZE);
setvbuf(stdout,outbuf,_IOFBF,SIZE);
}
}IO; struct Task {
char word[];
long long v;
bool operator > (Task &a){ /*重载为优先级比较符*/
return v < a.v || v == a.v && strcmp(word, a.word) < ;
}
}task[MAX]; /*在parent和child之间找到最高优先级代替parent*/
int replacePa(int x)
{
int pa = x;
if (RCHILD(x) <= n)
pa = PRIOR(task, x, PRIOR(task, LCHILD(x), RCHILD(x)));
else if (LCHILD(x) <= n)
pa = PRIOR(task, x, LCHILD(x));
return pa;
} /*下滤(向下调整堆)*/
void percolateDown(int x)
{
int rp = replacePa(x);
while (rp != x) {
swap(task[rp], task[x]);
x = rp;
rp = replacePa(x);
}
} /*批量建堆(堆积)*/
void heapify()
{
for (int i = n / ; i >= ; i--)
percolateDown(i);
} int main()
{
scanf("%d%d", &n, &m);
for (int i = ; i <= n; i++)
scanf("%lld%s", &task[i].v, task[i].word);
heapify(); for (int i = ; n && i < m; i++)
{
printf("%s\n", task[].word);
task[].v *= ;
if (task[].v >= INF)
task[] = task[n--];
percolateDown();
} return ;
}

ACM/ICPC 之 优先级队列+设置IO缓存区(TSH OJ-Schedule(任务调度))的更多相关文章

  1. ACM/ICPC 之 "嵌套"队列 -插队(POJ2259)

    这里插队的意思就是排队时遇到熟人则插到其后,否则排到队尾.(这个习惯不太好)(题意) 题目要求我们模拟“插队模型”和队列的入队和出队完成此算法. 由于题目的输入输出很多,此题的查找操作(找到熟人)需要 ...

  2. ACM/ICPC 之 快排+归并排序-记录顺序对(TSH OJ-LightHouse(灯塔))

    TsingHua OJ 上不能使用<algorithm>头文件,因此需要手写快排(刚开始写的时候自己就出了很多问题....),另外本题需要在给横坐标排序后,需要记录纵坐标的顺序对的数量,因 ...

  3. ACM/ICPC 之 双向链表_构造列表-模拟祖玛 (TSH OJ-Zuma(祖玛))

    这一题是TsingHua OJ上的一道题目,学堂在线的一位数据结构老师的题目(原创),所以我直接把题目先贴下来了,这道题对复习双向链表很有帮助,而且也对数据结构中List,也就是对列表的回顾也是很有帮 ...

  4. 个推基于 Apache Pulsar 的优先级队列方案

    作者:个推平台研发工程师 祥子 一.业务背景在个推的推送场景中,消息队列在整个系统中占有非常重要的位置.当 APP 有推送需求的时候, 会向个推发送一条推送命令,接到推送需求后,我们会把APP要求推送 ...

  5. 【转】lonekight@xmu·ACM/ICPC 回忆录

    转自:http://hi.baidu.com/ordeder/item/2a342a7fe7cb9e336dc37c89 2009年09月06日 星期日 21:55 初识ACM最早听说ACM/ICPC ...

  6. 用Redis实现优先级队列

    在最近在面试过程中,张先森遇到一个面试官这么问,如果一个并发很大的消息应用,想要根据请求的优先级来处理,该怎么做.我当时只是笼统地回答用redis,面试官点了点头,这个问题就此通过. 那么用redis ...

  7. OpenStack入门篇(五)之KVM性能优化及IO缓存介绍

    1.KVM的性能优化,介绍CPU,内存,IO性能优化 KVM CPU-->qemu进行模拟ring 3-->用户应用 (用户态,用户空间)ring 0-->操作系统 (内核态,内核空 ...

  8. 体验Rabbitmq强大的【优先级队列】之轻松面对现实业务场景

    说到队列的话,大家一定不会陌生,但是扯到优先级队列的话,还是有一部分同学是不清楚的,可能是不知道怎么去实现吧,其实呢,,,这东西已 经烂大街了...很简单,用“堆”去实现的,在我们系统中有一个订单催付 ...

  9. 如何基于RabbitMQ实现优先级队列

    概述 由于种种原因,RabbitMQ到目前为止,官方还没有实现优先级队列,只实现了Consumer的优先级处理. 但是,迫于种种原因,应用层面上又需要优先级队列,因此需求来了:如何为RabbitMQ加 ...

随机推荐

  1. Android Studio-设置代码自动提示

    None:代表模糊匹配(推荐). First Letter: 根据首字母进行匹配. All:与First Letter类似,不过匹配结果比First Letter多.

  2. 正则表达式基础---转自 Python正则表达式指南 前边

    1. 正则表达式基础 1.1. 简单介绍 正则表达式并不是Python的一部分.正则表达式是用于处理字符串的强大工具,拥有自己独特的语法以及一个独立的处理引擎,效率上可能不如str自带的方法,但功能十 ...

  3. django view

    当请求一个页面时,Django 创建一个包含有关请求数据的 HttpRequest 对象,并将它作为第一个参数传给视图函数,每个视图函数处理完相应逻辑后返回一个 HttpResponse 对象,Htt ...

  4. 【CISP笔记】操作系统安全

    账号安全设置 默认管理账号Administrator更名,设置密码(字母.数字.大小写字母.特殊字符,长度在8位以上). 本地安全策略 打开方式 win+R 输入ecpol.msc 账号锁定策略 用户 ...

  5. JavaScript中 window.parent 、window.top、window.self代表的含义

    在应用有frameset或者iframe的页面时,parent是父窗口,top是最顶级父窗口(有的窗口中套了好几层frameset或者iframe),self是当前窗口, opener是用open方法 ...

  6. CSS样式案例(1)-文字的排版

    本篇介绍的是小窗文字内容的排版,通过该篇文章可以让小伙伴们熟悉以下几个知识点: word-space.overflow.text-overflow. 最终的展示效果如下: 参考步骤: 1. 建立htm ...

  7. 大数据之pig 命令

    1.pig与hive的区别 pig和hive比较类似的,都是类sql的语言,底层都是依赖于hadoop    走的mapreduce任务.    pig和hive的区别就是,想要实现一个业务逻辑的话, ...

  8. 网页兼容浏览器测试工具Multibrowser

    网页兼容性测试工具(MultiBrowser),有firefox,chrome,IE 下载

  9. oracle 行列转换的运用

    问题: 员工表: A(E_ID,NAME,) 部门表:  B(D_ID,D_NAME) 员工与部门关系:C(ID,E_ID,D_ID) SELECT  A.E_ID,A.NAME ,B.D_NAME ...

  10. mac os 基本命令

    unix 系统命令行 ,仅供参考   目录操作   命令名 功能描述 使用举例   mkdir 创建一个目录 mkdir dirname   rmdir 删除一个目录 rmdir dirname   ...