观察题意,要求求出 个二次函数的当 取正整数值时的前 个最小值。考虑使用小根堆实现。
我们先将每个二次函数在 时的值压入小根堆中,然后取 次小根堆的最小值,每次取值之后看当前取的最小值对应的是哪个二次函数,随后将当前 的值加一,并将新的值压入小根堆中,如此即得答案。
#include <iostream>
#include <cstring>
#include <iomanip>
#include <cmath>
#include <vector>
#include <algorithm>
#include <queue>
using namespace std;
#define ll long long
#define ull unsigned long long
#define debug(x) cout << #x << "=" << x << "\n";
int n, m;
const int maxn = 1e4 + 10;
struct func
{
ll a, b, c;
} f[maxn];
struct Pair
{
int i;
ll x;
ll val;
bool operator>(const Pair &other) const
{
return val > other.val;
}
};
ll calc(ll a, ll b, ll c, ll x)
{
return a * x * x + b * x + c;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin >> n >> m;
for (int i = 1; i <= n; i++)
cin >> f[i].a >> f[i].b >> f[i].c;
priority_queue<Pair, vector<Pair>, greater<Pair>> q;
for (int i = 1; i <= n; i++)
q.push({i, 1, calc(f[i].a, f[i].b, f[i].c, 1)});
while (m--)
{
cout << q.top().val << " ";
int i = q.top().i;
ll x = q.top().x;
q.pop();
x++;
q.push({i, x, calc(f[i].a, f[i].b, f[i].c, x)});
}
return 0;
}