洛谷2085 最小函式值(堆)

2022-05-14 14:54:37 字數 1796 閱讀 3329

點此看題面

大致題意:給你\(n\)個形如\(f_i(x)=a_ix^2+b_ix+c_i(a_i,b_i,c_i,x∈n^*)\)的函式,請你求出所有函式的所有函式值中最小的前\(m\)個值。

顯然,我們可以發現乙個性質:對於每乙個函式,它的值肯定隨著\(x\)的增大而增大

也就是說,最終答案的\(x\)肯定小於\(m\),我們就可以考慮對於每乙個函式,求出\(x=[1..m]\)時的值,然後將所有的值排序一遍,輸出前\(m\)小的即可。

由於上面的那個性質,我們可以發現,對於同乙個函式,如果\(x=k\)時的值是最終的乙個答案,那麼\(x=k-1\)時的值顯然也是最終的乙個答案,因為\(x=k-1\)時的值是小於\(x=k\)時的值的。

推廣可得,如果\(x=k\)時的值是最終的乙個答案,那麼\(x=[1..k]\)時的值都是最終的答案

既然這樣,我們又可以得到,只有\(x=k-1\)時的值是最終的乙個答案了,\(x=k\)時的值才有可能是最終的乙個答案

這樣一來,我們就可以用堆(優先佇列)來進行優化了。

首先,我們將每乙個函式\(x=1\)時的值加入堆中,然後,進行\(m\)次操作,每次操作取出堆頂的值並將其輸出,然後將當前函式的\(x\)加\(1\)後得到的值重新加入堆中。

我們可以發現,在整個過程中,對於每乙個值我們只需要記錄三個資訊:值的大小屬於哪乙個函式以及當前的\(x\)

因為每一次操作的時間複雜度是\(o(logn)\)的,因此總複雜度是\(o(mlogn)\)。

#include#define max(x,y) ((x)>(y)?(x):(y))

#define min(x,y) ((x)<(y)?(x):(y))

#define ll long long

#define ull unsigned long long

#define swap(x,y) (x^=y,y^=x,x^=y)

#define tc() (a==b&&(b=(a=ff)+fread(ff,1,100000,stdin),a==b)?eof:*a++)

#define pc(ch) (pp_<100000?pp[pp_++]=(ch):(fwrite(pp,1,100000,stdout),pp[(pp_=0)++]=(ch)))

#define fi first//減少**量,用fi表示第乙個元素,se表示第二個元素,th表示第三個元素

#define se second.first

#define th second.second

#define n 10000

int pp_=0;char ff[100000],*a=ff,*b=ff,pp[100000];

using namespace std;

int n,m,a[n+5],b[n+5],c[n+5];

typedef pair> status;//對於每乙個值,需要記錄3個資訊

priority_queue,greater> q;//乙個堆(優先佇列)

inline void read(int &x)

inline void write(int x)

int main()

return fwrite(pp,1,pp_,stdout),0;

}

洛谷P2085 最小函式值 堆

有n nn個函式,分別為f1,f2,f nf1,f2,fn f1,f2,fn。定義fi x a i x2 bi x ci x n fi x a i times x 2 b i times x c i x n fi x ai x2 b i x ci x n 給定這些a ia i ai b ib i b...

洛谷P2085 最小函式值 大根堆

題目 或者分析 首先,每個二次函式在x 0上單調遞增 其次,用大根堆,把第乙個函式的m個函式值存入。從第二個函式開始,如果函式值比結點值小,則存入大根堆。說明 為什麼不用小根堆?答 對於小根堆而言,最大元素未必在堆尾。用小根堆,卡9個點 ac include includeusing namespa...

洛谷 P2085 最小函式值

有n個函式,分別為f1,f2,fn。定義fi x ai x 2 bi x ci x n 給定這些ai bi和ci,請求出所有函式的所有函式值中最小的m個 如有重複的要輸出多個 輸入格式 輸入資料 第一行輸入兩個正整數n和m。以下n行每行三個正整數,其中第i行的三個數分別位ai bi和ci。ai 10...