題目傳送門
你有n
nn個零件,給你m
mm個區間,其中:
y i=
∑i=l
iri(
a[i]
.w
>w)
∗∑i=
liri
(a[i
].
w>w)
∗a[i
].
vy_i=\sum_^(a[i].w>w)*\sum_^(a[i].w>w)*a[i].v
yi=i=
li∑
ri
(a[i
].w>w)
∗i=l
i∑r
i(
a[i]
.w>w)
∗a[i
].v然後你可以調整w
ww,使得∣∑y
i−k∣
|\sum y_i-k |
∣∑yi−
k∣最小並輸出這個值
我們發現y(w
)y(w)
y(w)
是乙個單調遞減的函式,所以就可以通過二分來求得最優答案,但是在二分判斷的時候該如何快速解決呢?我們需要乙個字首和預處理一下,然後再列舉區間計算就可以了,複雜度是o((
n+m)
×log
wmax
)o ( (n+m) \times log w_ )
o((n+m
)×lo
gwma
x)。
#include
#include
#include
#include
using
namespace std;
struct node
a[400001];
long
long l[
400001
],r[
400001];
long
long n,m;
long
long s;
long
long ans;
long
long b[
400001];
long
long c[
400001];
long
long tot;
long
long he1[
400001];
long
long he2[
400001];
bool
check
(long
long x)
}long
long he=0;
for(
long
long i=
1;i<=m;i++
) ans=
min(ans,
abs(he-s));
if(he>s)
return1;
else
return0;
}void
erfen
(long
long l,
long
long r)
long
long mid=
(l+r)/2
;if(check
(c[mid]))
else
}int
main()
for(
long
long i=
1;i<=m;i++
)sort
(b+1
,b+n+1)
; b[0]
=-1e5;
for(
long
long i=
1;i<=n;i++)}
c[0]=
0;c[tot+1]
=b[n]+1
; ans=
(long
long)(
1ll<<60)
-1;erfen(0
,tot+1)
; cout<'\n'
;return0;
}
noip2011 聰明的質檢員
題目描述 小t 是一名質量監督員,最近負責檢驗一批礦產的質量。這批礦產共有 n 個礦石,從 1到n 逐一編號,每個礦石都有自己的重量 wi 以及價值vi 檢驗礦產的流程是 1 給定m 個區間 li,ri 2 選出乙個引數 w 3 對於乙個區間 li,ri 計算礦石在這個區間上的檢驗值yi 這批礦產的...
noip2011提高組 聰明的質檢員
這道題要找乙個引數 這二分妥妥的。不然就t成翔吧。o o 每一次二分 都要預處理 cnt i 表示 對於當前二分到的引數 前 i 個有多少符合要求 sum i 表示 對於當前二分的引數 前 i 個符合要求的點的點權和 然後就按著題意來吧 找到 使結果比標準值小的 最靠近的那乙個 引數 再考慮這個引數...
NOIP2011提高組 聰明的質檢員
這道題很明顯要用二分猜答案,猜w的值,再來check。這裡我用的字首和的方法來check,求出前i個大於w 的個數和價值和,然後列舉每乙個區間,算就好了。注 要注意用longlong 考試的時候我就是這個錯了 具體程式如下 include include include include includ...