洛谷p1314 聰明的質監員

2022-02-19 20:25:30 字數 1491 閱讀 6114

聰明的質監員【題目鏈結】

有關演算法:

二分答案;

但是你只二分答案是不夠的,因為你check會炸,所以還要考慮字首和;

首先假裝我們的check已經寫好了,main函式:

int

main()

if(ls==s)

if(ls>s)

}printf(

"%lld

",min(ans1,ans2));

return0;

}

輸入沒有什麼可以說的,然後是二分答案,二分答案的話,從0~最大的wi;

二分的標準套路,先計算mid,用check函式判應該往左區間二分還是右區間二分,比較不好想的就是怎麼判斷往左區間還是右區間二分,這裡可以想到,當我們求出的中間值的y之後,如果發現它比s小,那麼如果要找更小的差距,應該讓y的值更大才有可能,那麼如果讓y的值更大,我們應該選入更多的礦產,所以我們應該使二分的答案減小,因此r=mid-1;然後這裡記錄兩個答案,ans1,ans2,分別記錄的是求得的值小於s的最小差,求得值大於s的最小差(顯然等於s時就直接輸出不需要再繼續迴圈了);

然後如果沒有找到使差為0的w,我們就輸出ans1和ans2中較小的乙個;

好了講完了;

並沒有講完啊,我們還莫得講check函式;

最簡單的方法,暴力掃瞄:

ll check(ll x) 

y+=(cnt*sum);

}return

y;}

然後你會發現你t成這樣:

y;}sum[i]表示1~i所有點中所有wi>=二分答案的的礦產的v之和,cnt[i]表示1~i以內所有點中所有wi>=二分答案的礦產個數;

然後處理應該很好理解,不再贅述;

然後再一次for迴圈,對於每個區間,利用維護的字首和計算sum*cnt,然後相加即為答案;

#include#define ll long long

using

namespace

std;

inline ll read()

ll n,m,w[

200001],v[200001],s,_l[200001],_r[200001],sum[200001],cnt[200001

];ll _abs(ll x)

ll check(ll x)

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

returny;}

intmain()

if(ls==s)

if(ls>s)

}printf(

"%lld

",min(ans1,ans2));

return0;

}

end-

洛谷 P1314 聰明的質監員

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

洛谷P1314 聰明的質監員

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

洛谷 P1314 聰明的質監員

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