Luogu P2085 最小函数值

P2085 最小函数值

题目描述

有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个数应该输出到一行,用空格隔开。

 

输入输出样例

输入样例#1:
3 10
4 5 3
3 4 5
1 7 1
输出样例#1:
9 12 12 19 25 29 31 44 45 54

说明

数据规模:n,m<=10000

 

Solution

//先计算出x=1时候的情况存Heap里
//然后每次找最小时,插入当前的最小的所属的函数f[i](x+1)到root ,然后维护小根堆
(为什么?根据不等式的性质if a<b then a*c<b*c while c>0)
//w记录当前的函数最大的x
//name[i]表示第I个节点的是第几个函数

//insert插入一个新元素到堆,然后维护堆的性质,这里是维护小根堆
//get得到当前最小值就是root,然后删掉把最后的一个元素作为root然后维护小根堆

 1 program wonder;
 2 const
 3   inf='minval.in';
 4   outf='minval.out';
 5 var
 6   len,i,j,n,tmp,ans,m:longint;
 7   heap,w,a,b,c,name:array[0..10000] of longint;
 8 
 9 procedure swap(var aa,bb:longint);
10 var t:longint;
11 begin
12   t:=aa;  aa:=bb;  bb:=t;
13 end;
14 
15 procedure insert(tmp:longint);
16 var
17   i:longint;
18 begin
19   inc(len);
20   heap[len]:=tmp; name[len]:=len;
21   i:=len;
22   while (i>1) and (heap[i div 2]>heap[i]) do
23   begin
24     swap(heap[i],heap[i div 2]);
25     swap(name[i],name[i div 2]);
26     i:=i div 2;
27   end;
28 end;
29 
30 procedure ch;
31 var
32  dad,son:longint;
33  stop:boolean;
34 begin
35   write(heap[1],' ');
36   inc(w[name[1]]);
37   heap[1]:=w[name[1]]*w[name[1]]*a[name[1]]+w[name[1]]*b[name[1]]+c[name[1]];
38   dad:=1;
39   stop:=false;
40   while ((dad*2+1<=len) or (dad*2<=len)) and (not stop) do
41   begin
42    if (heap[dad*2+1]>heap[dad*2]) or (dad*2+1>len) then
43     son:=dad*2
44     else son:=dad*2+1;
45    if heap[dad]<=heap[son] then stop:=true
46     else begin
47            swap(heap[dad],heap[son]);
48            swap(name[dad],name[son]);
49            dad:=son;  //!!!!
50          end;
51   end;
52 end;
53 
54 begin
55   assign(input,inf);  assign(output,outf);
56   reset(input);   rewrite(output);
57 
58   readln(n,m);
59   for i:= 1 to n do
60   begin
61     read(a[i],b[i],c[i]);
62     tmp:=a[i]+b[i]+c[i];
63     w[i]:=1;
64     insert(tmp);
65   end;
66 
67   for i:= 1 to m do ch;
68 
69   close(input); close(output);
70 end.

 

posted @ 2017-04-29 20:22  bobble  阅读(199)  评论(0编辑  收藏  举报