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]<<' '; }