題意:
n n
個礦石,每個礦石都有自己的重量 wi
' role="presentation" style="position: relative;">wiw
i,以及價值vi
v
i。接下來會進行以下四個操作:
1.給定
m m
個區間[l
i,ri
]' role="presentation" style="position: relative;">[li
,ri]
[li,
ri];
2.選出乙個引數
w w
; 3.對於乙個區間[l
i,ri
]' role="presentation" style="position: relative;">[li
,ri]
[li,
ri],計算礦石在這個區間上的檢驗值yi
=∑j1
∗∑jv
j,j∈
[li,
ri]並
且wj>=
w yi=
∑j1∗
∑jvj
,j∈[
li,r
i]並且
wj
>=w,
j j
是礦石編號。
4.這批礦產的檢驗結果y=
∑imy
i' role="presentation" style="position: relative;">y=∑
miyi
y=∑i
myi
給定乙個
s s
,求|s
−y|' role="presentation" style="position: relative;">|s−
y||s
−y|的最小值。
我們發現,
w w
的值越大,
y' role="presentation" style="position: relative;">y
y的值越小,所以當
y>
s y
>
s時,我們需要增大
w w
的值,反之亦然。
我們二分
w' role="presentation" style="position: relative;">w
w的值,對於每個二分到的
w w
值,我們根據要求求出∑j
1' role="presentation" style="position: relative;">∑j1
∑j1和
∑jvj
∑ jv
j,然後列舉每乙個區間,求出
y y
的值。最後根據
y' role="presentation" style="position: relative;">yy和
s s
的值判斷增大還是減小
w' role="presentation" style="position: relative;">w
w即可。
#include
#define ll long long
using
namespace
std;
ll w[202000],v[202000],sum[202000],le,ri,summ,maxx;
ll n,m,s,l[202000],r[202000],cnt[202000],ans=1e+12;
bool check(ll mid)
summ=0;
for(ll i=1;i<=n;++i)
else
}for(ll i=1;i<=m;++i)
if(sreturn
true;
return
false;
}int main()
le=0,ri=maxx;
for(ll i=1;i<=m;++i)
scanf("%lld%lld",&l[i],&r[i]);
ll mid;
while(ri>=le)
cout
0;}
NOIP 2011 聰明的質檢員 二分答案
先解釋一下這個式子 就是說如果區間 li,ri 中 wj w的個數 乘以 所有的wj w的價值的和。那麼我們可以二分w的值,通過y與s的值來調整w,具體來講,只要當下的y大於s,那麼增加mid 增大mid質量 否則減小mid。至於check,我們可以o n 的預處理字首和 and 字首積。總複雜度 ...
NOIP2011 聰明的質檢員(二分答案)
小t 是一名質量監督員,最近負責檢驗一批礦產的質量。這批礦產共有 n 個礦石,從 1到n 逐一編號,每個礦石都有自己的重量 wi 以及價值vi 檢驗礦產的流程是 1 給定m 個區間 li,ri 2 選出乙個引數 w 3 對於乙個區間 li,ri 計算礦石在這個區間上的檢驗值yi 這批礦產的檢驗結果y...
NOIP2011 選擇客棧 二分,STL
有 n 間客棧,每間客棧按某種色調裝飾,總共 k 種,每家有最低消費 w i 兩個人打算選擇同種色調的兩家不同客棧入住,同時在他們之間要有一間客棧的 w i le p 求選擇的方案數。先將所有滿足 w i le p 的 i 標記為可用的,其它的標記為不可用的。考慮對於每乙個左端點,向右找到第乙個可用...