题目大意
给n个函数。Fi(x)=Ai*x^2+Bi*x+Ci 。给定这些Ai、Bi和Ci,请求出所有函数的所有函数值中最小的m个。
输入
3 10
4 5 3
3 4 5
1 7 1
输出
9 12 12 19 25 29 31 44 45 54
思路
维护一个小根堆,里面的值为,按照要求每次输出堆顶,并将堆顶函数中的x加1再下调整个堆,直到输出m次堆顶。
代码
var
p,x,i,n,m,k,f,zz,tot:longint;
heap,a,b,c,w,s:array[0..40000]of longint;
procedure swap(var a,b:longint);
var t:longint;
begin
t:=a;a:=b;b:=t;
end;
procedure up(x:longint);
begin
while(heap[x]<heap[x div 2])and(x>1)do
begin
swap(heap[x],heap[x div 2]);
swap(w[x],w[x div 2]);
swap(s[x],s[x div 2]);
x:=x div 2;
end;
end;
procedure down(x:longint);
begin
swap(heap[x],heap[n]);
swap(w[x],w[n]);
swap(s[x],s[n]);
dec(n);
while x*2<=n do
begin
x:=x*2;
if(heap[x+1]<heap[x])and(x+1<=n)then inc(x);
if heap[x]<heap[x div 2] then
begin
swap(heap[x],heap[x div 2]);
swap(w[x],w[x div 2]);
swap(s[x],s[x div 2]);
end
else exit;
end;
end;
begin
read(m,k);
for i:=1 to m do
begin
read(a[i],b[i],c[i]);
inc(n);
heap[n]:=a[i]+b[i]+c[i];
w[n]:=i;
s[n]:=1;
up(n);
end;
repeat
write(heap[1],' ');
f:=w[1];
zz:=s[1];
down(1);
inc(zz);
inc(n);
heap[n]:=a[f]*sqr(zz)+b[f]*zz+c[f];
w[n]:=f;
s[n]:=zz;
up(n);
inc(tot);
until tot=k;
end.