P1314 聰明的質監員 二分答案

2022-04-30 21:27:15 字數 1665 閱讀 5277

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

1 、給定mm個區間[l_i,r_i][l**i,r**i];

2 、選出乙個引數ww;

3 、對於乙個區間[l_i,r_i][l**i,r**i],計算礦石在這個區間上的檢驗值y_iy**i:

這批礦產的檢驗結果yy 為各個區間的檢驗值之和。即:y_1+y_2...+y_my1+y2...+y**m

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

看到區間操作,首先想到可能資料結構,但是我一看。資料範圍嚇人,如果你一定要用的話,祝您線段樹過百萬。

分析題目,我們需要求乙個限制條件的最小值,很容易想到二分答案。看到題述公式,經驗告訴我們這個式子可以分開求,也就是每次check時求一組滿足\(w_j>w\)的\(m\)個詢問的\(\sum_j1\)和\(\sum_jv_j\),然後乘起來就得到答案。但是\(o(nm)\)的求肯定會爆掉,我們就自然而然地考慮乙個字首和的優化,減少大量計算。

#include#include#include#include#include#include#include#include#define inf 999999999999

#define pi acos(-1.0)

#define n 200010

#define mod 2520

#define e 1e-12

#define ll long long

using namespace std;

inline ll read()

while(c>='0'&&c<='9')

return x*f;

}inline ll max(ll x,ll y)

inline ll min(ll x,ll y)

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

res+=(tmp1[r[i]]-tmp1[l[i]-1])*(tmp2[r[i]]-tmp2[l[i]-1]);

if(res-s==0)

if(res-s>0) return 1;

else return 0;

}int main()

for(int i=1;i<=m;++i) l[i]=read(),r[i]=read();

ll l=minn-1,r=maxx+1;

ll ans=0x3f3f3f3f3f3f3f3f;

while(l>1;

if(check(mid)) l=mid;

else r=mid-1;

res=llabs(res-s);//注意longlong型別的絕對值函式要用這個,否則會溢位

ans=min(ans,res);//找最優解

} printf("%lld\n",ans);

return 0;

}

洛谷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...

P1314 聰明的質監員

原題連線 首先題號好評qwq 1314 意思就是 我們要在第 i 個區間 li ri 裡找到所有的 j,使得 wj w,求出這些 j 的價值總和及符合條件的 j 的個數,那麼這個區間的貢獻就是這個價值總和乘上 j 的個數,然後我們要算所有區間的貢獻的總和 y 最後輸出 y s 的絕對值的最小值,其中...