Luogu P1631

题意很好懂,不作分析

很容易想出一个解法是求出每一个和,排序后取前n个。

当然这种做法妥妥的会MLE+TLE

我们会发现实质上这种做法的缺点在于存入了大量不需要的数据。

那么该怎么进行优化呢?

观察题目,易得下列关系

a[1]+b[1]<=a[2]+b[1]<=...<=a[n]+b[1]

a[1]+b[2]<=a[2]+b[2]<=...<=a[n]+b[2]

a[1]+b[3]<=a[2]+b[3]<=...<=a[n]+b[3]

....................................

a[1]+b[n]<=a[2]+b[n]<=...<=a[n]+b[n]

很显然第一个答案必定会是a[1]+b[1]。

那么第二个答案一定会是a[1]+b[2]吗?未必如此。

假设有这样一组数据:

  1. n=3;
  2. a={1,1,3}
  3. b={3,4,13}

不难得出第一个答案会是4(a[1]+b[1]),第二个答案也是4(a[2]+b[1])。

由此看出,我们在取得一个答案后,应该将他在不等式中的下一项存入候选答案中。

对于候选答案的储存,我使用了优先队列的方式,不知道开一个数组不断排序能不能过。

代码奉上:

  1. #include<cstdio>
  2. #include<queue>
  3. #include<vector>
  4. using namespace std;
  5. priority_queue<pair<long long,int>> que;
  6. long long n,a[100005],b[100005],ans[200005],step[200005];
  7. int main()
  8. {
  9. scanf("%lld",&n);
  10. for (int i=1;i<=n;i++) scanf("%lld",&a[i]);
  11. for (int i=1;i<=n;i++) scanf("%lld",&b[i]);
  12. for (int i=1;i<=n;i++)
  13. {
  14. pair<long long,int> tmp(-a[i]-b[++step[i]],i);
  15. //取相反数是为了因为stl的优先队列优先级默认为从大到小。
  16. que.push(tmp);
  17. }
  18. for (int i=1;i<=n;i++)
  19. {
  20. long long val=que.top().first;int tmp=que.top().second;
  21. printf("%lld ",-val);
  22. que.pop();
  23. pair<long long,int> now(-a[tmp]-b[++step[tmp]],tmp);
  24. que.push(now);
  25. }
  26. return 0;
  27. }

【Luogu P1631】序列合并的更多相关文章

  1. Luogu P1631 序列合并

    题目 开一个堆,先把所有\(a[i]+b[1]\)压进优先队列. 然后每次把最小的取出来,把对应的\(a[i]\)的下一个\(b[j]\)拿出来加进去. #include<bits/stdc++ ...

  2. 洛谷P1631 序列合并

    P1631 序列合并 236通过 657提交 题目提供者xmyzwls 标签堆 难度普及+/提高 提交该题 讨论 题解 记录 最新讨论 为什么不行? 题目描述 有两个长度都是N的序列A和B,在A和B中 ...

  3. P1631 序列合并

    P1631 序列合并 有两个长度都是N的序列A和B,在A和B中各取一个数相加可以得到N^2N2个和,求这N^2N2个和中最小的N个. 对于100%的数据中,满足1<=N<=100000. ...

  4. 洛谷 - P1631 - 序列合并 - 堆

    https://www.luogu.org/problemnew/show/P1631 序列a中每个数首先都和序列b中的最小元素配对(虽然好像不是很必要这么早插进来?) 每次从堆顶取出最小的和输出答案 ...

  5. P1631 序列合并 洛谷

    https://www.luogu.org/problem/show?pid=1631 题目描述 有两个长度都是N的序列A和B,在A和B中各取一个数相加可以得到N^2个和,求这N^2个和中最小的N个. ...

  6. 洛谷 P1631 序列合并

    题意简述 有两个长度都是N的序列A和B,在A和B中各取一个数相加可以得到N^2个和,求这N^2个和中最小的N个. 题解思路 大根堆,先存入n个和,再比较大小,改变堆中元素. 代码 #include & ...

  7. luogu 1631 序列合并

    priority_queue的使用,注意 a[1]+b[1],a[1]+b[2],a[1]+b[3],a[1]+b[4].......a[1]+b[n] a[2]+b[1]......... .. a ...

  8. 洛谷 P1631 序列合并(优先队列)

    传送门 解题思路 首先读入a.b数组后,sort一遍(从小到大),然后把a[1]+b[1],a[2]+b[1],a[3]+b[1]……a[n]+b[1]全部加入一个优先队列q(小根堆). 然后从一到n ...

  9. 【洛谷】P1631: 序列合并

    P1631 序列合并 题目描述 有两个长度都是N的序列A和B,在A和B中各取一个数相加可以得到N2个和,求这N2个和中最小的N个. 输入输出格式 输入格式: 第一行一个正整数N: 第二行N个整数Ai​ ...

随机推荐

  1. AS报错:lambda expressions are not supported at this language level

    AS报错:lambda expressions are not supported at this language level 解决方法 打开打开 File --> Project Stuct ...

  2. vue表单和组件使用

    表单: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title ...

  3. 如何获取比 dism.log 更详细的日志

    正文 在工作中,曾经遇到过一个问题. 有一个 component,名字叫做 Oxford Adaptive Learning Dictionary,是一款牛津词典的应用.这个 component,需要 ...

  4. Unity4-用户输入

    Input是一个类,可以接收用户的输入 使用AddComponentMenu("Demo1/InputTest1"),将脚本加入到工程中. //例子: void Update() ...

  5. gedit一些小的新发现

    写应该还有一些人正在像我一样用gedit呢. 现在vim,gedit,guide三党还是互相瞧不起呢. 我写这一篇是想稍微交流一下gedit的一些乱七八糟的玩意,非gedit党勿喷. 有些人连一些比较 ...

  6. MongoDB自学------(1)MongoDB4.0安装

    一.环境 操作系统 安装包 安装方式 Ubuntu18.04 mongodb4.0 apt安装 Ubuntu18.04 mongodb4.0 docker安装 二.apt安装 sudo apt-key ...

  7. 小白学 Python(20):迭代器基础

    人生苦短,我选Python 前文传送门 小白学 Python(1):开篇 小白学 Python(2):基础数据类型(上) 小白学 Python(3):基础数据类型(下) 小白学 Python(4):变 ...

  8. 域名解析 | A记录 ,CNAME,MX,NS 你懂了吗

    域名解析 | A记录 ,CNAME,MX,NS 你懂了吗 域名解析 什么是域名解析?域名解析就是国际域名或者国内域名以及中文域名等域名申请后做的到IP地址的转换过程.IP地址是网路上标识您站点的数字地 ...

  9. 如何学习python,个人的一些简单见解

    什么是重要的东西 思考学习是一个什么样的过程 我们每个人都学习过数学,肯定都知道数学的学习过程是什么,我们刚开始学习数学的时候会学习一些简单的公式和概念,比如加减乘除,随着学习的深入,我们发现在大学之 ...

  10. canvas绘制工作流之绘制节点

    上一篇我们介绍了canvas绘制工作流的大概步骤,接下来会有系列文章细致的介绍怎么用canvas绘制工作流:这篇文章主要介绍用canvas绘制流程节点. 绘制前我们需要先准备一张节点图片,例如::好了 ...