luogu P1314 聰明的質監員 x

2022-04-06 05:19:25 字數 3520 閱讀 2818

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

1 、給定m 個區間[li,ri];

2 、選出乙個引數 w;

3 、對於乙個區間[li,ri],計算礦石在這個區間上的檢驗值yi:

這批礦產的檢驗結果y 為各個區間的檢驗值之和。即:y1+y2...+ym

若這批礦產的檢驗結果與所給標準值s 相差太多,就需要再去檢驗另一批礦產。小t

不想費時間去檢驗另一批礦產,所以他想通過調整引數w的值,讓檢驗結果盡可能的靠近

標準值s,即使得s-y 的絕對值最小。請你幫忙求出這個最小值。

輸入格式:

輸入檔案qc.in 。

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

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

接下來的m 行,表示區間,每行2 個整數,中間用空格隔開,第i+n+1 行表示區間[li,ri]的兩個端點li 和ri。

注意:不同區間可能重合或相互重疊。

輸出格式:

輸出檔名為qc.out。

輸出只有一行,包含乙個整數,表示所求的最小值。

輸入樣例#1:

5 3 15 

1 5

2 5

3 5

4 5

5 5

1 5

2 4

3 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 < wi, vi≤10^6,0 < s≤10^12,1 ≤li ≤ri ≤n 。

思路+

坑點:二分答案+字首和

1.首先來看給出公式,

公式含義:就是在說從li到ri區間之內的,中間的所有w值超過w的項的個數乘上這些(滿足條件的)礦石的v的和就是我們求所要的y啦!!!

2.因為w的值越大,得出的y越小,是單調的,所以一點需要注意的是l跟r的變化什麼的.

3.要求出的是那個離標準值最近的y.而不是第乙個大於等於或是第乙個大於標準值的y. (此y非彼y???)

4.分析一下題,可以得出w的值只需要在那一坨wi中取就好了,對結果是沒有任何影響的

可是為什麼呢?因為公式...

5.其實我們看到這個題,想到二分答案是不難的,但是如果就直接上二分答案,簡單暴力地求和什麼的,就會超時,時間複雜度o((m*n)log w). 你想啊,暴力的話,兩個迴圈,時間複雜度完美的**:差不多o(m*n)吧. 然後加上二分(log w)就是上面的複雜度了. 然後粗略計算極限資料,僅僅乙個計算y的函式差不多就會爆掉呢(可能吧,我看的dalao的部落格).

6.處理字首和的時候:

因為w是在不斷變化的,所以只需要再重新更新一下字首和就行. 差不多就是將滿足條件的弄上,不行的丟掉吧,大概是這樣.

7.時間複雜度:

應該是o((m+n)*log w)的複雜度(或者o(ac)). 這題就是個二分(log w(列舉的w嘛))+字首和 (因為每個check函式中都有兩個迴圈,乙個迴圈到n,處理字首和,迴圈到m求y.(m個區間嘛~)

8.不開long long見祖宗, 多年oi一場空.

9.要取abs(ans-s)的最小值(絕對值哦!),不要只取ans-s的最小值(因為可能會出來負值),如果不的話的話當ans

10.ans的初始化最大值要夠!!!不要賦成0x77f什麼的,(賦值為1e11差不多是可以的)這個最值(0x77f)對於其中35分的資料是不夠大的,目測來看至少要到1e11吧,然後1e10會wa掉5個測試點(額..65分)呢,因為這個題會爆int,然而0x77f只是最大int.

**:

///

額...至於格式什麼的,這個就隨你便啦,不順眼可以改嘛~

#include #include

#include

#include

#define ll long long

using

namespace

std;

const

int m = 2e5 + 233

;int

n,m;

ll s;

///注意這裡,s是long long型的,因為資料範圍是到10^12嘛~

intw[m],v[m],l[m],r[m];

ll num[m],sum[m];

///num陣列記錄滿足條件區間內個數.

///sum陣列記錄滿足條件區間內對應的v值的和

int l=1e7,r=0

;ll lmin(ll a,ll b)

int max(int a,int

b)ll check(

int x)///

注意返回值!!!!

*////

memset(sum,0,sizeof(sum));

///memset(num,0,sizeof(num));

for(int i=1;i<=n;i++)///

o((m+n)*log w)

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

return

yy;}

void

works()

ans=lmin(ans,abs(s-y));

///注意這裡的s-y要取絕對值

} printf(

"%lld\n

",ans);

}void

reads()

intmain()

view code

額...因為我比較蠢嘛,所以參考了好多dalao的部落格,如下(不是按順序來的哈):

1.

2.

3.

4.

+

xxy 大佬的現場(教)指導

end.

luogu P1314 聰明的質監員

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

luogu P1314 聰明的質監員

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

洛谷1314 聰明的質監員

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