前言
有一个东西卡了我一会
折叠N*或N+
正整数集 (由全体正整数组成的集合) N*:={1,2,3,…,n,…}
题目
洛谷P2085
OJ1370
给出n个ai,bi,ci。定义一个函数
fi(x)=aix2+bix+ci(x∈N∗)fi(x)=aix2+bix+ci(x∈N∗)
然后求最小的m个数
解题思路
这道题比较简单,一下就想到了。最重要的是得知道:
fi(1)<fi(2)<fi(3)<...<fi(n)<...fi(1)<fi(2)<fi(3)<...<fi(n)<...
然后就开始时都是x=1的,开一个小根堆,然后取最小的输出并且将那个f的x累加。然后维护
代码
#include<cstdio>
#include<algorithm>
using namespace std;
struct woc{int ans,ai,bi,ci,xi;//结构体
};
woc a[10001];
int n,m,num;
void up(int x)//维护堆
{while (x>1 && a[x/2].ans>a[x].ans){swap(a[x/2],a[x]);x/=2;}
}
void down(int x)//维护堆
{int y;while (x*2<=num && a[x*2].ans<a[x].ans || x*2+1<=num && a[x*2+1].ans<a[x].ans){y=x*2;if (y+1<=num && a[y].ans>a[y+1].ans) y++;swap(a[y],a[x]);x=y;}
}
int main()
{scanf("%d%d",&n,&m);for (int i=1;i<=n;i++){num++;scanf("%d%d%d",&a[num].ai,&a[num].bi,&a[num].ci);a[num].xi=1;a[num].ans=a[num].ai*a[num].xi*a[num].xi+a[num].bi*a[num].xi+a[num].ci;//求值up(num);//建堆}输入while (m>0){printf("%d ",a[1].ans);//输出a[1].xi++;//累加xa[1].ans=a[1].ai*a[1].xi*a[1].xi+a[1].bi*a[1].xi+a[1].ci;//重新求值down(1);//维护堆m--;//减少}
}