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[n]+b[1].......a[n]+b[n] 先放入每一行的第1个,a代表行,b代表列,弹出的值在哪一行,再新加入这一行的下一个元素 类似cdq减少维度 #include<bits/stdc++.h> #define rep(i,x,y) for(register int i=x;i<=…
题目描述 有n个函数,分别为F1,F2,-,Fn.定义Fi(x)=Ai*x^2+Bi*x+Ci (x∈N*).给定这些Ai.Bi和Ci,请求出所有函数的所有函数值中最小的m个(如有重复的要输出多个). 输入输出格式 输入格式: 输入数据:第一行输入两个正整数n和m.以下n行每行三个正整数,其中第i行的三个数分别位Ai.Bi和Ci.Ai<=10,Bi<=100,Ci<=10 000. 输出格式: 输出数据:输出将这n个函数所有可以生成的函数值排序后的前m个元素.这m个数应该输出到一行,用空…
题目 开一个堆,先把所有\(a[i]+b[1]\)压进优先队列. 然后每次把最小的取出来,把对应的\(a[i]\)的下一个\(b[j]\)拿出来加进去. #include<bits/stdc++.h> using namespace std; namespace IO { char ibuf[(1<<21)+1],obuf[(1<<21)+1],st[15],*iS,*iT,*oS=obuf,*oT=obuf+(1<<21); inline char Get…
P1631 序列合并 236通过 657提交 题目提供者xmyzwls 标签堆 难度普及+/提高 提交该题 讨论 题解 记录 最新讨论 为什么不行? 题目描述 有两个长度都是N的序列A和B,在A和B中各取一个数相加可以得到N^2个和,求这N^2个和中最小的N个. 输入输出格式 输入格式: 第一行一个正整数N: 第二行N个整数Ai,满足Ai<=Ai+1且Ai<=10^9; 第三行N个整数Bi, 满足Bi<=Bi+1且Bi<=10^9. [数据规模] 对于50%的数据中,满足1<…
Luogu 3246 序列 考虑莫队,不算特别优秀,但足以通过此题. 用莫队做,先考虑在当前区间右边加入一个数对答案的影响,其他三种情况同理. 若加入新数的区间为 \([L,R]\) ,那么加的贡献就是 \([L,R],[L+1,R]\dots [R,R]\) 这些区间最小值之和. 用单调栈预处理出每个数 \(a_i\) 左边第一个比它小的数的位置 \(sl\) ,那么它被记作最小值的区间就是 \([sl+1,R],[sl+2,R]\dots[i,R]\) ,被算了 \(i-sl\) 次.那么就…
P1631 序列合并 有两个长度都是N的序列A和B,在A和B中各取一个数相加可以得到N^2N2个和,求这N^2N2个和中最小的N个. 对于100%的数据中,满足1<=N<=100000. 思路巧妙,直接看代码 #include <cstdio> #include <algorithm> #include <iostream> #include <queue> #include <cstring> #include <algori…
P1631 序列合并 题目描述 有两个长度都是N的序列A和B,在A和B中各取一个数相加可以得到N2个和,求这N2个和中最小的N个. 输入输出格式 输入格式: 第一行一个正整数N: 第二行N个整数Ai​, 满足Ai​≤Ai+1​且Ai​≤109; 第三行N个整数Bi​, 满足Bi​≤Bi+1​且Bi​≤109. 输出格式: 输出仅一行,包含N个整数,从小到大输出这N个最小的和,相邻数字之间用空格隔开. 输入输出样例 输入样例#1: 复制 3 2 6 6 1 4 8 输出样例#1: 复制 3 6 7…
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…
https://www.luogu.org/problem/show?pid=1631 题目描述 有两个长度都是N的序列A和B,在A和B中各取一个数相加可以得到N^2个和,求这N^2个和中最小的N个. 输入输出格式 输入格式: 第一行一个正整数N: 第二行N个整数Ai,满足Ai<=Ai+1且Ai<=10^9; 第三行N个整数Bi, 满足Bi<=Bi+1且Bi<=10^9. [数据规模] 对于50%的数据中,满足1<=N<=1000: 对于100%的数据中,满足1<…
此算法涉及一个重要数学结论:如果A[k/2-1]<B[k/2-1],那么A[0]~A[k/2-1]一定在第k小的数的序列当中,可以用反证法证明. 算法思想如下: 1,假设A长度为m,B长度为n,m>n,反之亦然. 2,拆分k=pa+pb. 3,如果A[pa-1]<b[pb-1],那证明第A[0]~A[pa-1]一定在合并后k小数序列中.所以,可以把A的前面pa个数字截掉,递归,同理砍掉B数组. 4,递归的边界条件是if m=0,返回B[k-1],如果k = 1(找第一个数)就返回min[…
https://www.luogu.org/problemnew/show/P1631 序列a中每个数首先都和序列b中的最小元素配对(虽然好像不是很必要这么早插进来?) 每次从堆顶取出最小的和输出答案,然后尝试为这个ai配对下一个bj,要是没有的话--说明都是他一个人贡献完了. #include<bits/stdc++.h> using namespace std; typedef long long ll; int n; int a[100005]; int b[100005]; struc…
思路来自题解 作者: Red_w1nE 更新时间: 2016-11-13 20:46 在Ta的博客查看  72 最近有点忙 没时间贴代码了== [分析] 首先,把A和B两个序列分别从小到大排序,变成两个有序队列.这样,从A和B中各任取一个数相加得到N^2个和,可以把这些和看成形成了n个有序表/队列: A[1]+B[1] <= A[1]+B[2] <= … <= A[1]+B[N] A[2]+B[1] <= A[2]+B[2] <= … <= A[2]+B[N] …… A…
传送门 首先,把A和B两个序列分别从小到大排序,变成两个有序队列.这样,从A和B中各任取一个数相加得到N2个和,可以把这些和看成形成了n个有序表/队列: A[1]+B[1] <= A[1]+B[2] <= … <= A[1]+B[N] A[2]+B[1] <= A[2]+B[2] <= … <= A[2]+B[N] …… A[N]+B[1] <= A[N]+B[2] <= … <= A[N]+B[N] 接下来,就相当于要将这N个有序队列进行合并排序:…
Luogu P1090 [解题思路] 刚看到这题的时候,第一反应就是每次取两个最小,然后重新排序,再取最小.但是这样会TLE. 既然找最小的,那就可以利用单调队列了.显然输入的数据是不具有单调性的,但是可以排一次序,使之具有单调性. 这题需要两个队列,一个队列用于存储最先给出的堆,另一个队列用于存储合并后的堆. 值得一提的是,后面合并出来的堆,一定比前面合并出来的要大. 也就是说队列的单调性在这里是自然而然的,不需要维护的. 此时我们可以选择的操作有三种: 在队列1中选择最小两个 在队列2中选择…
题目描述 在一个园形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分. 试设计出1个算法,计算出将N堆石子合并成1堆的最小得分和最大得分.   题解 我们目测一个dp方程 设f[i][j]表示i到j合并的最小(大)价值   那么 dp的时候按照区间长度递增来dp 首先最大值,根据单调性 肯定是从和转移来的 最小值的时候.这个东西满足四边形不等式 设表示使i~j最优的分界点 首先当时 满足 且 那么枚举中间点的时…
题目描述 在一个园形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分. 试设计出1个算法,计算出将N堆石子合并成1堆的最小得分和最大得分. 输入输出格式 输入格式: 数据的第1行试正整数N,1≤N≤100,表示有N堆石子.第2行有N个数,分别表示每堆石子的个数. 输出格式: 输出共2行,第1行为最小得分,第2行为最大得分. 输入输出样例 输入样例#1: 4 4 5 9 4 输出样例#1: 43 54 区间动态规…
题目大意 有两个序列A,B,在A和B中各取一个数相加能得到$n^2$个和.求出这些和前n小的数字. 题解 首先这道题不可以用自己想的什么A序列B序列各两个指针的自己发明的模拟算法,用这样的算法只能是绝路一条. 此题入手点在于优化暴力.暴力算法是枚举所有的$A_i+B_j$,排个序,然后一个个输出.我们优化之处便是如何动态枚举$A_i,B_j$. 此时我曾想对两个数组都动态,这样想就走到了死胡同. 我们可以让A不动态,B动态,也就是优先队列里储存的数对里包含所有的$A_i$,但每个$A_I$只对应…
题意简述 有两个长度都是N的序列A和B,在A和B中各取一个数相加可以得到N^2个和,求这N^2个和中最小的N个. 题解思路 大根堆,先存入n个和,再比较大小,改变堆中元素. 代码 #include <cstdio> #include <algorithm> using namespace std; int n, a[100001], b[100001], ans[100001]; int cnt, heap[100001]; void up(int x); void down(in…
https://www.luogu.org/problemnew/show/P2023 线段树双懒标记下放 #include <bits/stdc++.h> using namespace std; ; #define LL long long #define lson jd << 1 #define rson jd << 1 | 1 LL w[N << ], size[N << ], fadd[N << ], fmul[N <…
(是道线段树好题√) 题目链接 题外话:这道题我也不知道卡了自己多少天,从初赛之前就开始做,一直到现在才a掉(时间跨度得有将近十天了吧?) 线段树,嗯,好像很简单的样子. 但事实上因为自己太菜了,卡了好久: 第一遍的思路简单的很,因为完全没有考虑标记下传的顺序问题,qf(取反)标记和chg(修改)标记各自下传各自的,于是乎就一直10分10分(没有好好写线段树Ⅱ的锅),咋改都不对,也没看出自己错在哪了: 然后被建议重构代码,于是尝试暴力出奇迹,\(O(nm)的暴力+O_2\)结果拿到了90pts?…
链接 P3411 序列变换 如果要最小化答案,那么就最大化不移动的数. 那么不移动的子序列一定是最后答案的一段连续区间,而移动的数我们是一定有办法把他们还原的. 设\(f_{i}\)表示\(i\)点的最长长度,转移实际上是恒定的,即\(f_{i}=f_{j}+1\),其中\(j\)是\(i\)的前驱且唯一确定. 把\(a\)数组离散化后直接查值域即可,复杂度\(O(nlogn)\). #include<bits/stdc++.h> #define R register int using na…
嘟嘟嘟 这是一道splay基础题. 最坑的一点是,因为有些节点可能没有左儿子或右儿子,所以必须把t[0].Max赋成-INF! 因为这个调了半天,看来回头复习复习splay是对的-- #include<cstdio> #include<iostream> #include<cmath> #include<algorithm> #include<cstring> #include<cstdlib> #include<cctype&…
题目链接 直接暴力搞是\(n\)方的复杂度.\(n^2\)个数选\(n\)个最小的,容易想到堆. 我们堆里记录两个信息:到\(A\)数组哪个位置了,到\(B\)数组哪个位置了, 我直接把这两个信息存在一个\(int\)里了. 然后按\(A[i]\)+\(B[j]\)建立小根堆,每次取出堆顶并输出,然后弹出,在把这个堆顶的\(B\)数组的指针右移,加入堆,重复\(n\)次就好了. 为了降低常数,我手写了堆. #include <cstdio> #include <cstring> #…
传送门 解题思路 首先读入a.b数组后,sort一遍(从小到大),然后把a[1]+b[1],a[2]+b[1],a[3]+b[1]……a[n]+b[1]全部加入一个优先队列q(小根堆). 然后从一到n循环,每一次取出队列中的最小的元素(假设是a[i]+b[j]),输出数值,然后把数值修改为a[i]+b[j+1],存入队列. 为什么呢? 很显然,我们把所有可能的情况列成一张表: a[1]+b[1],a[2]+b[1],a[3]+b[1],……,a[n]+b[1]; a[1]+b[2],a[2]+b…
本题要求实现一个函数,将两个链表表示的递增整数序列合并为一个递增的整数序列. 函数接口定义: List Merge( List L1, List L2 ); 其中List结构定义如下: typedef struct Node *PtrToNode; struct Node { ElementType Data; /* 存储结点数据 */ PtrToNode Next; /* 指向下一个结点的指针 */ }; typedef PtrToNode List; /* 定义单链表类型 */ L1和L2是…
先放上luogu的石子合并题目链接 这是一道环形DP题,思想和能量项链很像,在预处理过程中的手法跟乘积最大相像. 用一个m[][]数组来存储石子数量,m[i][j]表示从第 i 堆石子到第 j 堆石子的总数. 接下来三重循环 i 表示合并操作的起始位置, j 表示合并操作的终点,也就是把 i 到 j 合并 k表示间断点,即 i 到 j 合并过程中选择k点来作为合并位置 状态转移方程 f[i][j]=max(f[i][j],f[i][k]+f[k+1][j]+m[i][k]+m[k+1][j]);…
02-线性结构1 两个有序链表序列的合并(15 point(s)) 本题要求实现一个函数,将两个链表表示的递增整数序列合并为一个非递减的整数序列. 函数接口定义: List Merge( List L1, List L2 ); 其中List结构定义如下: typedef struct Node *PtrToNode; struct Node { ElementType Data; /* 存储结点数据 */ PtrToNode Next; /* 指向下一个结点的指针 */ }; typedef P…
6-5 两个有序链表序列的合并 (15 分)   本题要求实现一个函数,将两个链表表示的递增整数序列合并为一个非递减的整数序列. 函数接口定义: List Merge( List L1, List L2 ); 其中List结构定义如下: typedef struct Node *PtrToNode; struct Node { ElementType Data; /* 存储结点数据 */ PtrToNode Next; /* 指向下一个结点的指针 */ }; typedef PtrToNode…
luogu 问题本质是把\(a_i\)作为\(i\)的父亲,然后如果有环就不合法,否则每次要取数,要满足取之前他的父亲都被取过(父亲为0可以直接取),求最大价值 贪心想法显然是要把权值大的尽量放在后面,这等价于把权值小的尽量放在前面.所以如果当前最小的数没有父亲,显然直接取出来最优;如果有父亲,那么这个数应该在它的父亲被取之后马上取出来.这时我们把这两个点合并.之后重复此操作知道所有点被取完,就能得到答案 还有个问题是两个点合并后怎么取权值.两个点合并相当于两个序列合并,序列分别记为\(\{a_…
题目网址:https://www.luogu.com.cn/problem/P1880 题意是:给定一个序列,最小规则是相邻两个值的合并,开销是他们的和,将整个序列合并成一个值的情况下,求解该值的最小值和最大值. 代码如下: #include<bits/stdc++.h> using namespace std; typedef unsigned int ui; typedef long long ll; typedef unsigned long long ull; #define pf p…