LGOI P1314 聰明的質監員

2022-07-25 05:57:07 字數 2734 閱讀 8372

原題戳這裡

題目描述

小t是一名質量監督員,最近負責檢驗一批礦產的質量。這批礦產共有 \(n\) 個礦石,從 \(1\)到\(n\) 逐一編號,每個礦石都有自己的重量\(w_i\)以及價值\(v_i\) 。檢驗礦產的流程是:

給定m個區間\(l_i,r_i\)

選出乙個引數\(w\);

對於乙個區間\([l_i,r_i]\),計算礦石在這個區間上的檢驗值y

i:\[y_i= ( \sum_j 1)(\sum_j ),\quad j \in [l_i,r_i] ,\quad w_j \geq w

\]其中,\(j\)是礦石的編號。

這批礦產的檢驗結果\(y\) 為各個區間的檢驗值之和。即:\(y_1+y_2...+y_m\)

若這批礦產的檢驗結果與所給標準值\(s\) 相差太多,就需要再去檢驗另一批礦產。小t不想費時間去檢驗另一批礦產,所以他想通過調整引數\(w\) 的值,讓檢驗結果盡可能的靠近標準值\(s\),即使得\(s-y\) 的絕對值最小。請你幫忙求出這個最小值。

輸入格式

第一行包含三個整數\(n,m\),分別表示礦石的個數、區間的個數和標準值。

接下來的\(n\)行,每行\(2\)個整數,中間用空格隔開,第\(i+1\)行表示\(i\)號礦石的重量\(w_i\)和價值\(v_i\)。

接下來的\(m\) 行,表示區間,每行\(2\) 個整數,中間用空格隔開,第\(i+n+1\)行表示區間\([l_i,r_i]\)的兩個端點\(l_i\) 和\(r_i\)。注意:不同區間可能重合或相互重疊。

輸出格式

乙個整數,表示所求的最小值。

輸入輸出樣例

輸入 #1

5 3 15

1 52 5

3 54 5

5 51 5

2 43 3

輸出 #1

10說明/提示

【輸入輸出樣例說明】

當\(w\)選\(4\)的時候,三個區間上檢驗值分別為 \(20,5,0\) ,這批礦產的檢驗結果為 \(25\),此時與標準值\(s\)相差最小為\(10\)。

【資料範圍】

對於\(10\%\)的資料,有 \(1 ≤n ,m≤10\);

對於\(30\%\)的資料,有 \(1 ≤n ,m≤500\) ;

對於\(50\%\)的資料,有\(1 ≤n ,m≤5,000\);

對於\(70\%\) 的資料,有 \(1 ≤n ,m≤10,000\);

對於\(100\%\)的資料,有\(1 ≤n ,m≤200,000,0 < w_i,v_i≤10^6,0 < s≤10^,1 ≤l_i ≤r_i ≤n\)

很明顯這是乙個二分的板子,想都沒想就tle了

感覺這個題目的背景在任何程度上說都很奇怪啊

首先考慮函式\(y(w_)\),直覺上告訴我們\(y(w_)\)具有單調性。證明懶得寫。

其實是不會寫

\[y(w_)=\sum_i^m ( ( \sum_j 1) (\sum_j )),\quad j \in [l_i,r_i] ,\quad w_j \geq w_

\]接下來就是要找距離\(y(w_)-s\)零點最近的函式值。因為\(y(w_)\)是單調的,所以直接上二分。

\(1^ \quad\)

\(y(w_)-s \geq 0\),\(w_\)偏小,將其調大;

\(2^ \quad\)

\(y(w_)-s < 0\), \(w_\)偏大,將其調小;

↓然後隨便打了乙個\(y(w_)\)的函式,就**了。甚至一開始這個暴力寫法的下標還寫錯了,甚至還在這裡卡了好久

inline ll fy1(ll curw)

}y+=sumv_of_range*cnt_j;

}return y;

}

這裡優化的想法也不難,兩個字首陣列\(pre_n,pre_v\)即可。

但是沒辦法,每次呼叫\(y(w_)\),\(pre_n,pre_v\)都要重新計算。但是速度比原來還是快很多的。

詳見**。

#includeusing namespace std;

#define ll long long

inline int read()

const int n=200010;

const ll llinf=0x3f3f3f3f3f3f3f3f;

int v[n],w[n],l[n],r[n];

ll n,m,s;

ll pre_n[n],pre_v[n];

// inline ll fy1(ll curw)

// // }

// y+=sumv_of_range*cnt_j;

// }

// return y;

// }

inline ll fy(int curw)

else

}for(int i=1;i<=m;i++)

y+=(pre_n[r[i]]-pre_n[l[i]-1])*(pre_v[r[i]]-pre_v[l[i]-1]);

return y;

}int main()

for(int i=1;i<=m;i++)

ll l=minw-1,r=maxw+2,mid,ans=llinf;

while(l<=r)

printf("%lld",ans);

return 0;

}

洛谷1314 聰明的質監員

noip2011 day2 t1 題目描述 小t 是一名質量監督員,最近負責檢驗一批礦產的質量。這批礦產共有 n 個礦石,從 1到n 逐一編號,每個礦石都有自己的重量 wi 以及價值vi 檢驗礦產的流程是 1 給定m 個區間 li,ri 2 選出乙個引數 w 3 對於乙個區間 li,ri 計算礦石在...

luogu1314 聰明的質監員

題目描述 小t 是一名質量監督員,最近負責檢驗一批礦產的質量。這批礦產共有 n 個礦石,從 1到n 逐一編號,每個礦石都有自己的重量 wi 以及價值vi 檢驗礦產的流程是 1 給定m 個區間 li,ri 2 選出乙個引數 w 3 對於乙個區間 li,ri 計算礦石在這個區間上的檢驗值yi 這批礦產的...

洛谷1314 聰明的質監員

聰明的質檢員 小 t 是一名質量監督員,最近負責檢驗一批礦產的質量。這批礦產共有 n 個礦石,從 1 到 n 逐一編號,每個礦石都有自己的重量 wi 以及價值 vi。檢驗礦產的流程是 1 給定 m 個區間 li,ri 2 選出乙個引數 w 3 對於乙個區間 li,ri 計算礦石在這個區間上的檢驗值 ...