---恢复内容开始---

有n个函数,分别为F1,F2,...,Fn。定义Fi(x)=Ai*x^2+Bi*x+Ci(x∈N+)。给定这些Ai、Bi和Ci,请求出所有函数的所有函数值中最小的m个(如有重复的要输出多个)。

 

INPUT:

第一行输入两个正整数n和m(1<=m,n<=10000)。
以下n行每行三个正整数,其中第i行的三个数分别位Ai、Bi和Ci。输入数据保证1<=Ai<=10,1<=Bi<=100,1<=Ci<=10 000。

3 10
4 5 3
3 4 5
1 7 1

 

OUTPUT:

输出将这n个函数所有可以生成的函数值排序后的前m个元素。

这m个数应该输出到一行,用空格隔开。

9 12 12 19 25 29 31 44 45 54

 

思路:

题目很简单。

第一反应也和简单(爆搜):复杂度为(n*m)

把n个函数从1到的值算出来,存进优先队列。然后输出队列的前m项。但是0<m,n<10000;

数据大时就BOOM!!

正解:

开一个结构体

1 struct node
2 {
3     int a,b,c,x,ans;
4     friend bool operator < (node n1, node n2)
5     {
6         return n1.ans>n2.ans;
7     }
8 }f[maxn];

然后,在输入时将每个函数x=1时存进f[i].ans;

然后for循环+进出队列。

核心:

 

1 void work2()
2 {
3     node t=q.top();
4     t.x++;
5     t.ans=work(t);
6     q.pop();
7     q.push(t);
8 }

 

cpp:

 

 1 #include<iostream>
 2 #include<string>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<cstdio>
 6 #include<cmath>
 7 #include<iomanip>
 8 #include<queue>
 9 #include<vector>
10 using namespace std;
11 const int maxn=500001;
12 int n,m;
13 struct node
14 {
15     int a,b,c,x,ans;
16     friend bool operator < (node n1, node n2)
17     {
18         return n1.ans>n2.ans;
19     }
20 }f[maxn];
21 
22 int work(node t)
23 {
24     return t.a*t.x*t.x+t.b*t.x+t.c;
25 }
26 
27 priority_queue<node>q;
28 
29 void work2()
30 {
31     node t=q.top();
32     t.x++;
33     t.ans=work(t);
34     q.pop();
35     q.push(t);
36 }
37 
38 
39 int main()
40 {
41     /*freopen("2.in","r",stdin);
42     freopen("2.out","w",stdout);*/
43     //ios::sync_with_stdio(false);
44     cin>>n>>m;
45     for(int i=1;i<=n;i++)
46     {
47         cin>>f[i].a>>f[i].b>>f[i].c;
48         f[i].x=1;
49         f[i].ans=work(f[i]);
50     }
51     for(int i=1;i<=n;i++)
52         q.push(f[i]);
53     for(int i=1;i<=m;i++)
54     {
55         cout<<q.top().ans<<" ";
56         work2();
57     }
58     cout<<endl;
59     return 0;
60 }
View Code