p1241

本题需要输出对于所有函数值当x取正整数的时候最小的前m个

装作每次询问函数值复杂度为1,直接算的话需要算好多次啊(我承认刚开始以为0<=x<=n)。然后还要排序,复杂度爆炸。

考虑到本题只关注前m个,那我可以从对称轴出发,向左右算m/2个,这样计算的复杂度变成了m*n了,然后还要对数组更改什么的。

然而我们的单点插入单点询问正是堆的性质,这题可以上一个堆就可以A了。

并且由于AB大于0,那么对称轴一定小于0且函数在[1-+∞)上递增,代码又好写了许多。(膜拜杨宇航大佬Orz)

对于每个ABC从1开始遍历,F=f(k)表示x=k的函数值。如果当前堆内元素个数小于m就直接放进去,sum++。否则需要判断F与堆内最大值的关系:如果比它大了就break,否则可以放进堆里并把堆头扔掉。

最后逆序处理一波。

using namespace std;

priority_queue<int> dui;
int i,k,ta,tb,tc,F;
int n,m;
int sum;
int o[10010];
inline int f(int now)
{
    return ta*now*now+tb*now+tc;
}
int main()
{
    
    cin>>n>>m;
    for(i=1;i<=n;i++)
    {
        cin>>ta>>tb>>tc;        
        for(k=1;;k++)
        {
            F=f(k);
            if(sum<m)
                dui.push(F),sum++;
            else
                if(F>dui.top())
                    break;
                else
                    dui.pop(),dui.push(F);
        }
    }
    for(i=1;i<=sum;i++)
    {
        o[sum-i+1]=dui.top();
        dui.pop();
    }
    for(i=1;i<=sum;i++)
        cout<<o[i]<<' ';
}

 

posted @ 2018-09-09 18:16  zzuqy  阅读(155)  评论(0编辑  收藏  举报