一次奇怪的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. 查找(顺序表&有序表)

    [1]查找概论 查找表是由同一类型是数据元素(或记录)构成的集合. 关键字是数据元素中某个数据项的值,又称为键值. 若此关键字可以唯一标识一个记录,则称此关键字为主关键字. 查找就是根据给定的某个值, ...

  2. Hdu5737-Differencia(有序表线段树)

    题意很直观,我就不说了. 解析:这是我以前没有接触过的线段树类型,有序表线段树,每个节点申请了两段空间,主要是为了保存左边儿子会有多少比v小的,右边儿子会有多少比v小 的,所以在建树过程中要归并排序. ...

  3. Java数据结构与算法(1) - ch02有序表(OrderedArray)

    有序表需要掌握的插入方法,删除方法和二分法查找方法. 插入方法: 从前往后找到比要插入的值大的数组项,将该数组项及之后的项均后移一位(从最后一项起依次后移),最后将要插入的值插入当前数组项. 删除方法 ...

  4. java数据结构之有序表查找

    这篇文章是关于有序表的查找,主要包括了顺序查找的优化用法.折半查找.插值查找.斐波那契查找: 顺序优化查找:效率极为底下,但是算法简单,适用于小型数据查找: 折半查找:又称为二分查找,它是从查找表的中 ...

  5. JAVA通过继承线性表来实现有序表

    1,对于线性表而言,里面的元素是无序的,可以随意地将新元素增加到线性表中而不需要考虑该元素在线性表中的位置.但是,对于有序表而言,其中的元素是按照某种方式进行排序的,因此在有序表中插入元素时,需要按照 ...

  6. 查找->静态查找表->折半查找(有序表)

    文字描述 以有序表表示静态查找表时,可用折半查找算法查找指定元素. 折半查找过程是以处于区间中间位置记录的关键字和给定值比较,若相等,则查找成功,若不等,则缩小范围,直至新的区间中间位置记录的关键字等 ...

  7. 【IT笔试面试题整理】有序数组生成最小高度二叉树

    [试题描述]定义一个函数,输入一个有序数组生成最小高度二叉树 We will try to create a binary tree such that for each node, the numb ...

  8. UVa 11997 K Smallest Sums 优先队列&amp;&amp;打有序表&amp;&amp;归并

    UVA - 11997 id=18702" target="_blank" style="color:blue; text-decoration:none&qu ...

  9. 将两个各有n个元素的有序表归并成一个有序表,其最多的比较次数

    最多的比较次数是当两个有序表的数据刚好是插空顺序的时候,比如:第一个序列是1,3,5,第二个序列是2,4,6,把第二个序列插入到第一个序列中,先把第二个序列中的第一个元素2和第一个序列依次比较,需要比 ...

随机推荐

  1. nginx location指令详解

    Nginx的HTTP配置主要包括三个区块,结构如下: http { //这个是协议级别 include mime.types; default_type application/octet-strea ...

  2. C++强大背后

    转自MiloYip大神的博客 [原文]http://www.cnblogs.com/miloyip/archive/2010/09/17/behind_cplusplus.html 在31年前(197 ...

  3. Android开发DDMS找不到Emulator Control的方法

    1.右键DDMS,点击reset. 2.window->show view->other->android->Emulator Control

  4. (原创)对比组态软件,使用C#开发的服务器和客户端软件的优势

    在当前经济形势和市场环境下,中小企业面对萧条的消费市场,恶化的外部贸易环境,刚性支出高成本人工和生产要素,通货膨胀,隐性的腐化支出等各种因素的作用导致企业生存艰难,企业需要在各方面削减支出,拓展市场寻 ...

  5. python中用分别用selenium、requests库实现Windows认证登录

    最近在搞单位的项目,实现python自动化,结果在第一步就把我给拒之门外,查资料问大佬,问我们开发人员,从周一折腾到周五才搞定了 接下给大家分享一下 项目背景:我们系统是基于Windows平台实现的, ...

  6. Eclipse集成Git做团队开发:代码管理

    在日常开发工作中,我们通常使用版本控制软件管理团队的源代码,常用的SVN.Git.与SVN相比,Git有分支的概念,可以从主分支创建开发分支,在开发分支测试没有问题之后,再合并到主分支上去,从而避免了 ...

  7. PAT 1003我要通过!

    PAT 1003 我要通过! 答案正确"是自动判题系统给出的最令人欢喜的回复.本题属于 PAT 的"答案正确"大派送 -- 只要读入的字符串满足下列条件,系统就输出&qu ...

  8. 换个语言学一下 Golang (10)——并行计算

    如果说Go有什么让人一见钟情的特性,那大概就是并行计算了吧. 做个题目 如果我们列出10以下所有能够被3或者5整除的自然数,那么我们得到的是3,5,6和9.这四个数的和是23.那么请计算1000以下( ...

  9. jQuery 前端复选框 全选 反选 下拉菜单联动

    jQuery 页面中复选框全选.反选.下拉联动(级联) <!DOCTYPE html> <html lang="en"> <head> < ...

  10. Web消息推送框架windows部署实践

    一.官方下载地址:https://www.workerman.net/web-sender 二.解压至任意目录下,双击start_for_win.bat,效果如下图: 三.打开Chrome浏览器访问: ...