NOIP2011 聰明的質檢員

2021-09-28 21:58:06 字數 2094 閱讀 7957

題目傳送門

你有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...