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】序列合并的更多相关文章

  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. Andriod开发环境搭建

    一.相关安装文件准备

  2. 微软的分布式应用框架 Dapr Helloworld

    Dapr HelloWorld Dapr Distributed Application Runtime. An event-driven, portable runtime for building ...

  3. Node.js 使用 express-jwt 解析 JWT

    Node.js 上 Token 鉴权常用的是 passport,它可以自定义校验策略,但如果你是用 express 框架,又只是解析 JWT 这种简单需求,可以尝试下 express-jwt 这个中间 ...

  4. 关于Map集合注意事项

    今日代码中循环Map时,采用循环主键 Map<Integer,Map<Integer,String>> status =  new HashMap<>(); Set ...

  5. window10系统下,彻底删除卸载mysql

    本文介绍,在Windows10系统下,如何彻底删除卸载MySQL...1>停止MySQL服务开始->所有应用->Windows管理工具->服务,将MySQL服务停止.2> ...

  6. Azure 上的物联网产品介绍

    微软云Azure上物联网产品提供了从设备接入到设备与云的双向通信,到数据在云中存储,到数据分析,最后到数据展示的完整解决方案,本文主要介绍一些基本的概念,后续的章节中,会详细介绍每款产品的使用方法及步 ...

  7. C++学习笔记4_new和delete

    1. 默认的new和delete操作符new和delete是和c里面的mlloc和free是一样的,在堆中创建空间.堆中创建的,都要自己释放.C中void test(){ int *p=(int *) ...

  8. linux 查看磁盘信息

    一.查看磁盘和分区 ACCB947E:Home zhangsan$ df -h Filesystem Size Used Avail Capacity iused ifree %iused Mount ...

  9. Feign设置assessToken

    import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.an ...

  10. Docker swarm集群增加节点和删除节点

    Docker swarm集群增加节点 docker swarm初始化 docker swarm init docker swarm 增加节点 在已经初始化的机器上执行:# docker swarm j ...