一开始想的是求个导之类的,没有想过一步一步的算。每次把增量最小的++。

#include <bits/stdc++.h>
using namespace std;
const int N=1e5+5;
typedef long long ll;
struct node
{
    int x,num;
    ll sub,sum;
    bool operator <(const node b)const
    {
        return sub>b.sub;
    }
};
ll a[N],b[N],c[N];
ll fun(int i,int x)
{
    return a[i]*x*x+b[i]*x+c[i];
}
priority_queue<node>que;
bool vis[N];
int main()
{
    int n,m;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        while(!que.empty())
            que.pop();
        memset(vis,0,sizeof(vis));
        for(int i=1;i<=n;i++)
        {
            scanf("%lld%lld%lld",&a[i],&b[i],&c[i]);
            que.push({1,i,fun(i,2)-fun(i,1),fun(i,1)});
        }
        m-=n;
        while(m>0&&m--)
        {
            node now=que.top();
            que.pop();
            que.push({now.x+1,now.num,fun(now.num,now.x+2)-fun(now.num,now.x+1),fun(now.num,now.x+1)});
        }
        ll ans=0;
        while(!que.empty())
        {
            node now=que.top();//cout<<now.num<<":"<<now.x<<endl;
            que.pop();
            if(!vis[now.num])
            {
                ans+=now.sum;
                vis[now.num]=1;
            }
        }
        printf("%lld\n",ans);
    }
    return 0;
}