【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]吗?未必如此。
假设有这样一组数据:
n=3;
a={1,1,3}
b={3,4,13}
不难得出第一个答案会是4(a[1]+b[1]),第二个答案也是4(a[2]+b[1])。
由此看出,我们在取得一个答案后,应该将他在不等式中的下一项存入候选答案中。
对于候选答案的储存,我使用了优先队列的方式,不知道开一个数组不断排序能不能过。
代码奉上:
#include<cstdio>
#include<queue>
#include<vector>
using namespace std;
priority_queue<pair<long long,int>> que;
long long n,a[100005],b[100005],ans[200005],step[200005];
int main()
{
scanf("%lld",&n);
for (int i=1;i<=n;i++) scanf("%lld",&a[i]);
for (int i=1;i<=n;i++) scanf("%lld",&b[i]);
for (int i=1;i<=n;i++)
{
pair<long long,int> tmp(-a[i]-b[++step[i]],i);
//取相反数是为了因为stl的优先队列优先级默认为从大到小。
que.push(tmp);
}
for (int i=1;i<=n;i++)
{
long long val=que.top().first;int tmp=que.top().second;
printf("%lld ",-val);
que.pop();
pair<long long,int> now(-a[tmp]-b[++step[tmp]],tmp);
que.push(now);
}
return 0;
}
【Luogu P1631】序列合并的更多相关文章
- Luogu P1631 序列合并
题目 开一个堆,先把所有\(a[i]+b[1]\)压进优先队列. 然后每次把最小的取出来,把对应的\(a[i]\)的下一个\(b[j]\)拿出来加进去. #include<bits/stdc++ ...
- 洛谷P1631 序列合并
P1631 序列合并 236通过 657提交 题目提供者xmyzwls 标签堆 难度普及+/提高 提交该题 讨论 题解 记录 最新讨论 为什么不行? 题目描述 有两个长度都是N的序列A和B,在A和B中 ...
- P1631 序列合并
P1631 序列合并 有两个长度都是N的序列A和B,在A和B中各取一个数相加可以得到N^2N2个和,求这N^2N2个和中最小的N个. 对于100%的数据中,满足1<=N<=100000. ...
- 洛谷 - P1631 - 序列合并 - 堆
https://www.luogu.org/problemnew/show/P1631 序列a中每个数首先都和序列b中的最小元素配对(虽然好像不是很必要这么早插进来?) 每次从堆顶取出最小的和输出答案 ...
- P1631 序列合并 洛谷
https://www.luogu.org/problem/show?pid=1631 题目描述 有两个长度都是N的序列A和B,在A和B中各取一个数相加可以得到N^2个和,求这N^2个和中最小的N个. ...
- 洛谷 P1631 序列合并
题意简述 有两个长度都是N的序列A和B,在A和B中各取一个数相加可以得到N^2个和,求这N^2个和中最小的N个. 题解思路 大根堆,先存入n个和,再比较大小,改变堆中元素. 代码 #include & ...
- 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 ...
- 洛谷 P1631 序列合并(优先队列)
传送门 解题思路 首先读入a.b数组后,sort一遍(从小到大),然后把a[1]+b[1],a[2]+b[1],a[3]+b[1]……a[n]+b[1]全部加入一个优先队列q(小根堆). 然后从一到n ...
- 【洛谷】P1631: 序列合并
P1631 序列合并 题目描述 有两个长度都是N的序列A和B,在A和B中各取一个数相加可以得到N2个和,求这N2个和中最小的N个. 输入输出格式 输入格式: 第一行一个正整数N: 第二行N个整数Ai ...
随机推荐
- javascript函数前面加~波浪线的作用
如下,在函数前加上波浪号,其作用是把函数声明转换为表达式,这样就可以直接运行. ~function sayHello(){ console.log('hello'); }() 测试: 在console ...
- video1
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- ThreadPoolExecutor源码中的适配器模式
什么是适配器模式 网上已有很多的教程,不细讲了.可以参考:五分钟了解设计模式(3)---适配器模式 在适配器模式中,一定要识别清楚,Target Adaptee Adapter分别是哪些类或接口,这样 ...
- TCP/IP和Socket开发经验分享
当前与网络相关的业务主要是基于tcp/ip或http,熟悉j2ee的同学一定会对http场景下的开发比较了解.但是,精通tcp/ip以及如何构建一个直接基于tcp/ip层通讯的知识却不太多见.恰巧,最 ...
- 设计模式C++描述----10.装饰(Decorator)模式
一. 举例 我之前做过一个文件系统就叫 MyFileSys 吧,后来的话,客户想加入一些附加功能,比如压缩.加密.杀毒之类的操作,这些附加操作没有先后顺序,比如你可以先压缩再加密,也可以先杀毒再压缩, ...
- Android_Fragment
(一) Faragment有自己的生命周期 Fragment依赖于Activity Fragmen通过getActivity()可以获取所在Activity:Activity通过FragmentMan ...
- MIT线性代数:16.投影矩阵和最小二乘
- IDEA复制多行及对多行代码上下左右移动
复制: 复制一行可不需要选中 多行需要选中 mac:command+D window:ctrl+D 移动: 选中代码 左移:tab+shift 右移:tab 上移:shift+alt+向上方向键 下移 ...
- [考试反思]0719NOIP模拟测试6 + 0722NOIP模拟测试7
连续爆炸,颇为愉快. 第6次:Rank #4 第7次:Rank #9 对于第6次考试,个人比较满意,因为T1只是差了一个卡常. 因为在考试前两天刚讲了矩阵,满脑子都是矩阵,还想到了循环矩阵优化. 整个 ...
- 最新开源跳板机(堡垒机)系统 Jumpserver介绍
Jumpserver 是全球首款完全开源的堡垒机,使用 GNU GPL v2.0 开源协议,是符合 4A 的专业运维审计系统. Jumpserver 使用 Python / Django 进行开发,遵 ...