トピックへのリンク:https://www.luogu.org/problemnew/show/P1314
問題の意味:合計値が徐々に値Sに近づくように、m個の間隔が与えられると、製品の重量wをnおよびvの値が与えられ、各間隔は、パラメータWを含む式により算出されます
分析:Wは、全ての製品は、その後、最大値Yを満たしている、明らかに0であり、Wは、すべての製品が満たされていない、重みwの最大値よりも大きい場合、次いで、最小のYは、単調性は明らかであろう、我々この方法は、二分法を行うために使用することができます
すべての二点あれば、決意は、その後、要求間隔で、時間計算量はO(N * M)で、我々は接頭辞を使用する必要がありますし、O(N)用に最適化されます
各W、及びプレフィックスの時間については、W対応する重みは、W、現在の数プラス和アレイよりも大きい場合にそうでない場合は添加しません。
加えて、我々はあなたが別のレコードにANS番号を使用したいので、半分の時間、できるだけ近い標準値を作成する権利があります
ここで、絶対値関数である:()llabsはLLの数の絶対値とすることができます。
#include <ビット/ STDC ++ H> 使用して 名前空間STDを、 typedefの長い 長いLL。 const int型 MOD = 1E9 + 7 。 const int型 MAXN = 2E5 + 7 。 CONST LL INF = 1E18 + 7 。 CONST ダブル PI = ACOS( - 1 )。 LL ANS = infを、RES = infファイル。 LL N、M、S。 LL和[MAXN]、sum_n [MAXN]、W [MAXN]、V [MAXN]、L [MAXN]、R [MAXN]。 BOOL ISOK(INT X){ LLのY = 0 。 memsetの(合計、0、sizeof (合計)); memset(sum_n、0、はsizeof (sum_n))。 以下のために(int型 i = 1 ; iが<= N; iは++ ){ 場合(W [i]が> = x)の和[i]は=和[I- 1 ] + V [i]は、sum_n [I] = sum_n [I - 1 ] + 1 。 他和[I] =和[I- 1 ]、sum_n [I] = sum_n [I- 1 ]。 } のための(int型 I = 0 ;私がm <; Iは++ ){ Y + =(sum_n [R [I]] - sum_n [L [I] - 1 ])*(和[R [I]] -和[L [I] - 1 ])。 } //COUT << Y <<」「<< S << ENDL。 RESの=のllabs(Y- S)。 // coutの<< RES <<てendl; 場合(S> y)を返し 偽。 他に 返す 真。 } int型のmain(){ CIN >> N >> M >> S。 LL MN = INF、MX = - 1 。 以下のために(int型 i = 1 ; iが<= N; iが++ ){ scanf関数(" %のLLDの%のLLD "、&W [I]を、&V [I])。 MN = 分(MN、W [I])。 MX = MAX(MX、W [I])。 } 用(int型私は= 0 Iは++; Iがm < {) scanfの(" %Dの%のD "、&L [I]、&R&LT [I]); } int型左= MN- 1、右= MX + 2 ; // だけ右ボーダーMXを取得する場合、ケースは同様ミネソタ州ミネラルの全てが満たされていない含まれていないことができ 、一方(左<= 右){ int型 MID =(左+右)/ 2 ; IF(ISOK(MID))=左MID + 1を、 そうでなければ右半ば= 1 ; IF(RES <ANS)ANS = RES; // COUT ANS << << ENDL、 } coutの << ANS << てendl; リターン 0 ; }