函数值

sjtu4252

函数值

题目描述

有nn个开口向上的二次函数fi(x)=aix2+bix+cifi(x)=aix2+bix+ci
我们现在只考虑xx是整数的情况,对于每个整数xx用这nn个函数作用之都能得到nn个数,即使数值相同我们也认为是重复的多个
将xx取遍所有整数,在得到的无穷多个数中,求最小的kk个数并从小到大输出

输入格式

第一行两个数n,kn,k,表示序列长度和所求数个数
接下来nn行,每行三个数ai,bi,ciai,bi,ci,表示函数fi(x)fi(x)

输出格式

一行kk个数表示最小的kk个数

样例输入1

2 9
1 0 0
1 2 0

样例输出1

-1 0 0 0 1 1 3 3 4

数据规模

对于100%的数据有
0<ai0<ai
对于30%的数据有
bi%(2∗ai)=0bi%(2∗ai)=0
对于60%的数据有
bi%ai=0bi%ai=0
对于40%的数据有
n≤500n≤500
k≤500k≤500
对于70%的数据有
n≤3000n≤3000
k≤3000k≤3000
对于100%的数据有
n≤100000n≤100000
k≤100000k≤100000

代码

#pragma GCC optimize(3)
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<climits>
#include<queue>
#include<set>
#define max(x,y) ((x)>(y)?(x):(y))
#define min(x,y) ((x)<(y)?(x):(y))
#define swap(x,y) (x^=y,y^=x,x^=y)
using namespace std;
typedef long long ll;
const int N=1e6+50;
template<typename T>inline void read(T &x)
{
    x=0;
    T f=1;
    char c=getchar();
    for(; c<'0'||c>'9'; c=getchar()) if(c=='-') f=-1;
    for(; c>='0'&&c<='9'; c=getchar()) x=(x<<1)+(x<<3)+(c&15);
}
template<typename T>inline void print(T x)
{
    if(x<0) putchar('-'),x*=-1;
    if(x>=10) print(x/10);
    putchar(x%10+'0');
}
ll a[N],b[N],c[N];
struct node
{
    ll v,x,f;
};
node qq;
multiset<ll>pq;
priority_queue<node>q;
bool operator < (node a,node b)   //重载<
{
    return a.v>b.v;
}
ll fac(ll i,ll x)   //开ll
{
    return a[i]*x*x+b[i]*x+c[i];
}
int n,k;
ll t[N];
int main()
{
    read(n);read(k);
    for(int i=1;i<=n;i++)
    {
        scanf("%lld%lld%lld",a+i,b+i,c+i);
        t[i]=(-b[i])/(2*a[i]);
        q.push((node){fac(i,t[i]),t[i],i});
    }
    ll e,w,r,y;
    for(int i=1;i<=2*k;i++)    //只循环到k会wa,以防万一扩大入队数目
    {
        qq=q.top();
//        print(qq.v);
        //q.pop();
        pq.insert(qq.v);
        q.pop();
        if(qq.x==t[qq.f]){
        e=fac(qq.f,qq.x+1);
        w=fac(qq.f,qq.x-1);
        r=qq.x+1;
        y=qq.x-1;
        q.push((node){e,r,qq.f});
        q.push((node){w,y,qq.f});
        }
        else if(qq.x>t[qq.f])
        {
            e=fac(qq.f,qq.x+1);
            q.push((node){e,qq.x+1,qq.f});
        }
        else
        {
            e=fac(qq.f,qq.x-1);
            q.push((node){e,qq.x-1,qq.f});
        }
    }
    int temp=0;
    for(multiset<ll>::iterator it=pq.begin();it!=pq.end();it++) //set的遍历
    {
        cout<<*it<<' ';
        temp++;
        if(temp==k)
            break;
    }
    cout<<endl;
    return 0;
}

ps

  • vector 可用 emplace_back 代替 push_back 速度快一倍。
posted @ 2019-10-31 21:56  Anticlock  阅读(549)  评论(0编辑  收藏  举报