HUSTOJ 有序表的最小和
一次奇怪的AC经历。。。上周被这道题卡了3天。。。
传送门:http://oj.gdsyzx.edu.cn/problem.php?id=1475
题目描述
给出两个长度为n的有序表A和B,在A和B中各任取一个元素,可以得到n2个和,求这些和中最小的n个。(不要去重)
输入
第一行包含一个整数n(n<=400000); 第二行与第三行分别有n个整数,分别代表有序表A和B。整数之间由一个空格隔开,大小在长整型范围内,保证有序表的数据单调递增。
输出
输出共n行,每行一个整数,第i行为第i小的和。数据保证在长整型范围内。
样例输入
3
1 2 5
2 4 7
样例输出
3
4
5
先是在学校做了这道题,被归到了“队列”标签里,然后因为是求前n个最小值,那么肯定就是用优先队列啦。
我们先来看一个叫做k路归并问题的神奇玩意(抄的百度文库)

好的,看懂了上面我们进行下一步!把A和B数组所有元素的和看作n个有序表(如下)

如果直接按照k路归并的算法,“把每个表的当前元素放入二叉堆中”需要log n的时间,删除最小值,加入下一个元素(所有表的)又需要log n的时间,总共就需要 n^2 log n 的时间,400000的数据规模铁定爆了!!!
既然会爆,我们就来优化一下。先思考一下把一个元素放入二叉堆的条件是什么,是它在有序表中的前一个元素被弹出(不是被放入)!所以我们从a1+b1开始扫,每次入堆的时候都打上标记,如果这个元素出堆了,那么就把它所在的有序表的下一个元素入堆!
综上,O(n log n)!
代码:
#include <iostream>
#include <queue>
#include <algorithm> using namespace std;
int n,a[400005],b[400005],t[400005];
struct sb
{
int h,bj;
friend bool operator< (sb a1,sb b1)//带结构体的优先队列用法
{
return a1.h>b1.h;
}
}; priority_queue<sb> q; inline void write(int x)//快速写入
{
if(x>9) write(x/10);
putchar(x%10+'0');
} int main()
{
ios::sync_with_stdio(0); cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=n;i++) cin>>b[i]; for(int i=1;i<=n;i++)
{
sb temp;
temp.h=a[i]+b[++t[i]];
temp.bj=i;
q.push(temp);
write(q.top().h);
putchar('\n');
int bjt=q.top().bj;
if(t[bjt]<n)
{
temp.h=a[bjt]+b[++t[bjt]];
temp.bj=bjt;
}
q.push(temp);
q.pop();
}
}
HUSTOJ 有序表的最小和的更多相关文章
- 查找(顺序表&有序表)
[1]查找概论 查找表是由同一类型是数据元素(或记录)构成的集合. 关键字是数据元素中某个数据项的值,又称为键值. 若此关键字可以唯一标识一个记录,则称此关键字为主关键字. 查找就是根据给定的某个值, ...
- Hdu5737-Differencia(有序表线段树)
题意很直观,我就不说了. 解析:这是我以前没有接触过的线段树类型,有序表线段树,每个节点申请了两段空间,主要是为了保存左边儿子会有多少比v小的,右边儿子会有多少比v小 的,所以在建树过程中要归并排序. ...
- Java数据结构与算法(1) - ch02有序表(OrderedArray)
有序表需要掌握的插入方法,删除方法和二分法查找方法. 插入方法: 从前往后找到比要插入的值大的数组项,将该数组项及之后的项均后移一位(从最后一项起依次后移),最后将要插入的值插入当前数组项. 删除方法 ...
- java数据结构之有序表查找
这篇文章是关于有序表的查找,主要包括了顺序查找的优化用法.折半查找.插值查找.斐波那契查找: 顺序优化查找:效率极为底下,但是算法简单,适用于小型数据查找: 折半查找:又称为二分查找,它是从查找表的中 ...
- JAVA通过继承线性表来实现有序表
1,对于线性表而言,里面的元素是无序的,可以随意地将新元素增加到线性表中而不需要考虑该元素在线性表中的位置.但是,对于有序表而言,其中的元素是按照某种方式进行排序的,因此在有序表中插入元素时,需要按照 ...
- 查找->静态查找表->折半查找(有序表)
文字描述 以有序表表示静态查找表时,可用折半查找算法查找指定元素. 折半查找过程是以处于区间中间位置记录的关键字和给定值比较,若相等,则查找成功,若不等,则缩小范围,直至新的区间中间位置记录的关键字等 ...
- 【IT笔试面试题整理】有序数组生成最小高度二叉树
[试题描述]定义一个函数,输入一个有序数组生成最小高度二叉树 We will try to create a binary tree such that for each node, the numb ...
- UVa 11997 K Smallest Sums 优先队列&&打有序表&&归并
UVA - 11997 id=18702" target="_blank" style="color:blue; text-decoration:none&qu ...
- 将两个各有n个元素的有序表归并成一个有序表,其最多的比较次数
最多的比较次数是当两个有序表的数据刚好是插空顺序的时候,比如:第一个序列是1,3,5,第二个序列是2,4,6,把第二个序列插入到第一个序列中,先把第二个序列中的第一个元素2和第一个序列依次比较,需要比 ...
随机推荐
- 阿里云CentOS服务器下安装Golang1.13并配置代理
注:root账户或添加sudo命令运行. 下载到/usr/local位置并解压 cd /usr/local wget https://studygolang.com/dl/golang/go1.13. ...
- [SOJ #687]双生串(2019-11-6考试)/[hdu5431]AB String
题目大意 把所有仅包含\(AB\)的字符串按字典序排列,给你一个仅包含\(AB\)的字符串\(S\),然后有\(Q\)个问题,第\(i\)个问题给你\(k_i\),求不是\(S\)的子串中,第\(k_ ...
- pandas 学习 第十一篇:处理缺失值
Pandas中的缺失值是指nan.None和NaT.如果需要把inf 和 -inf视为缺失值,需要设置 pandas的选项: pandas.options.mode.use_inf_as_na = T ...
- Mysql中的排序查询
进阶3:排序查询 语法: select 查询列表 from 表 [where 筛选条件]order by 排序列表 [asc 升序 | desc降序] 例子 查询员工信息,要求工资从高到低 SELEC ...
- 爬虫--selenium之 chromedriver与chrome版本映射表(最新至v2.46版本chromedriver)
本文主要整理了selenium的chromedriver与chrome版本映射表,并且持续更新中..... 1.selenium之 chromedriver与chrome版本映射表(最新至v2.46版 ...
- SqlServer共用表达式(CTE)With As 处理递归查询
共用表表达式(CTE)可以看成是一个临时的结果集,可以再SELECT,INSERT,UPDATE,DELETE,MARGE语句中多次引用. 一好处:使用共用表表达式可以让语句更加清晰简练. 1.可以定 ...
- 来自GitHub的优秀开源项目系列
开发必看: 如何设计大型系统? 架构师技术图谱. 互联网Java工程师进阶扫盲 Java学习指南 Java工程师成神之路 有趣开源项目: 中华古诗词数据库 表情包博物馆
- MES应用案例 | 天博集团成功完成数字化转型
受到智能制造观念和技术的巨大且快速的影响,使得工业特别是汽车行业必须以最快速度赶上这场企业数字化转型的浪潮,唯有实现企业转型升级才能在这场速度战中占得先机.当然关于企业的转型升级,最为重要的是需要打造 ...
- 购买了一台阿里云ECS后安装Java项目运行环境
在docker等虚拟化技术大行其道的今天,我原本也想在我买的ECS服务器里全系使用docker技术,只可惜在我尝试后发现我的ECS配置不够高,整个服务器卡到爆炸,无奈只能使用最原始的方式. 我买的服务 ...
- VS code key shortcuts for windows
mac上的快捷键,尽量是选择像我用vs studio上靠近. ctrl+K+S: 显示快捷键列 ctrl+shift+p: 系统配置命令行 ctrl+p:项目中文件列表,选择文件 Alt+M:当前文件 ...