思路:堆
对于
n
n
n个函数且
F
i
(
x
)
=
A
i
x
2
+
B
i
x
+
C
i
(
x
∈
N
∗
)
F_i(x)=A_ix^2+B_ix+C_i (x\in N*)
Fi(x)=Aix2+Bix+Ci(x∈N∗) 来说,我们要求这
n
n
n个函数的前
m
m
m个函数值,并由小到大依次输出,我们很自然就可以想到用堆来存放函数值
最朴素的想法就是分别把这
n
n
n个函数,每个函数的前
m
m
m个值都放进一个小根堆中,那个对于这
n
m
nm
nm个值来说,前
m
m
m个值就是符合要求的值,但很不幸会
T
L
E
TLE
TLE…
进一步想,由于
x
,
A
i
,
B
i
,
C
i
∈
N
∗
x,A_i,B_i,C_i\in N*
x,Ai,Bi,Ci∈N∗,所以显而易见的是函数都是递增的,那么我们可以用一个大根堆
q
q
q,先将第一个函数的前
m
m
m个值都放入堆中,然后对接下来的每个函数的前
m
m
m个取值,如果函数值小于堆顶,就压入堆中,并将堆顶弹出,一旦函数值大于堆顶,由于函数递增,可以直接跳出这个循环,省略剩下明显不可能的值,达到优化的目的,最后将这
m
m
m个值放入数组,倒序输出即可
AC代码如下:
#include <bits/stdc++.h>
using namespace std;
const int N=1e4+10;
typedef long long ll;
int n,m;
priority_queue<int>q;
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
int A,B,C;
scanf("%d%d%d",&A,&B,&C);
for(int j=1;j<=m;j++){
int k=A*j*j+B*j+C;
if(i==1) q.push(k);
else{
if(k<q.top()){
q.push(k);
q.pop();
}
else break;
}
}
}
int ans[N];
for(int i=1;i<=m;i++){
ans[i]=q.top();
q.pop();
}
for(int i=m;i>=1;i--){
printf("%d ",ans[i]);
}
return 0;
}