8
16
2015
0

[题解]最小函数值(minval)

关键字:堆。

Link&Limit


[洛谷2085]

时间限制:1000ms  空间限制:131072kb

Description


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

Input Format


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

Output Format


输出将这n个函数所有可以生成的函数值排序后的前m个元素。这m个数应该输出到一行,用空格隔开。

Sample Input #1


3 10

4 5 3

3 4 5

1 7 1

Sample Output #1


9 12 12 19 25 29 31 44 45 54

Hint


对于100%的数据,n,m<=10000。

堆的基础题,与洛谷P1631类似。由于Ai,Bi,Ci>0,所以每一个函数在定义域内都是增函数。那么,我们将F1(1),F2(1)...Fn(1)全部加入小根堆,每次取出堆顶元素Fx(y),输出并将Fx(y+1)加入堆中,重复进行m次即可。

#include <cstdio>
struct node
{
    int id,now,sum;
    node operator = (node x)
    {
        id = x.id;
        now = x.now;
        sum = x.sum;
        return *this;
    }
};
struct heap
{
    node h[30010];
    int tot;
    heap() { tot = 0;}
    
    void add(node x)
    {
        int i = ++tot,j = i>>1;
        h[tot] = x;
        for(;i>1;i=j,j>>=1)
        {
            if(x.sum<h[j].sum) {h[i] = h[j]; h[j] = x;}
            else break;
        }
    }
    
    void del()
    {
        int i = 1,j = 2;
        node x = h[1] = h[tot--];
        for(;j<=tot;i=j,j<<=1)
        {
            if(j<tot) if(h[j+1].sum<h[j].sum) j++;
            if(x.sum>h[j].sum) {h[i] = h[j]; h[j] = x;}
            else break;
        }
    }
}heaps;

int n,m,a[10010],b[10010],c[10010];

int main()
{
    int i;
    scanf("%d%d",&n,&m);
    for(i=1;i<=n;i++)
    {
        scanf("%d%d%d",&a[i],&b[i],&c[i]);
        node x;
        x.id = i; x.now = 1; x.sum = a[i]+b[i]+c[i];
        heaps.add(x);
    }
    for(i=1;i<=m;i++)
    {
        printf("%d ",heaps.h[1].sum);
        node x = heaps.h[1];
        x.now++; x.sum = a[x.id]*x.now*x.now+b[x.id]*x.now+c[x.id];
        heaps.add(x);
        heaps.del();
    }
    return 0;
}
Category: 题解 | Tags: 洛谷 | Read Count: 686

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter

| Theme: Aeros 2.0 by TheBuckmaker.com