Http://acm.hdu.edu.cn/showproblem.php? PID = 1, 3884
Binary + Verification
Verify whether t peaches can be placed at the same point,
The T peach must be continuous. It is assumed that it exists in the interval [a, B].
One of the two endpoints in this interval must be full (so scan twice between the left and right)
Assume that point a is full.
Then locate the T peach.
Find the second (t + 1)/second peach in the middle (distance and minimum)
In this case, the middle position is obtained, and the left and right sides are located to verify whether the cost is exceeded.
Note: When T is an even number, there should be two peaches in the middle. After I think about it, it will be TLE, because my algorithm complexity is O (LGM * n * lgn) (M indicates the total number of peaches and N indicates the number of positions)
Later, we thought that the peach in the middle was the second (t + 1)/two, and it took over 900 Ms =!
# Include <iostream> # include <cstdio> # include <algorithm> # include <string. h >#include <cmath >#include <vector> using namespace STD ;__ int64 N, K; const int maxn = 10005; struct node {__ int64 x ;__ int64 P ;} A [maxn] ;__ int64 LB [maxn] ;__ int64 LC [maxn] ;__ int64 RB [maxn] ;__ int64 RC [maxn]; void solve () {LB [0] = 0, LC [0] = 0; For (INT I = 1; I <= N; I ++) {LB [I] = lb[ I-1] + A [I]. p; LC [I] = Lc [I-1] + A [I]. p * A [I]. x;} RB [n + 1] = 0, RC [n + 1] = 0; for (in T I = N; I> = 1; I --) {RB [I] = RB [I + 1] + A [I]. p; RC [I] = RC [I + 1] + A [I]. p * A [I]. X ;}} int find_left (int pur, int L, int R ,__ int64 v) {int ans = n + 1; while (L <= r) {int mid = (L + r)/2; If (Lb [Mid]-lb [pur-1] = V) return mid; else if (Lb [Mid]-lb [pur-1] <v) L = Mid + 1; else {If (mid <ans) ans = mid; R = mid-1 ;}}if (ANS = n + 1) Return-1; return ans ;}int find_right (int pur, int L, int R, __int64 v) {int ans = 0; while (L <= r) {int mid = (L + r)/2; if (rb [Mid]-Rb [pur + 1] = = V) return mid; else if (rb [Mid]-Rb [pur + 1] <v) r = mid-1; else {If (mid> ans) ans = mid; L = Mid + 1 ;}} if (ANS = 0) Return-1; return ans;} bool is_true (_ int64 T) // verify whether t peaches can be placed to the same point {int L = 0, r = 0, mid = 0 ;__ int64 Suk = 0; For (INT I = 1; I <= N; I ++) {Suk = 0; L = I; r = find_left (I, I, n, T); If (r =-1) continue; Mid = find_left (I, I, n, (t + 1)/2); Suk + = A [Mid]. x * (Lb [Mid-1]-lb L-1])-(LC [Mid-1]-LC L-1]); suk + = Lc [r-1]-LC [Mid]-A [Mid]. * (Lb [r-1]-lb [Mid ]); Suk + = (a [R]. p-(Lb [R]-lb L-1]-t) * (a [R]. x-A [Mid]. x); If (Suk <= k) return true;/* If (T % 2 = 0) {Suk = 0; Mid = find_left (I, I, n, (t + 2)/2); Suk + = A [Mid]. x * (Lb [Mid-1]-lb L-1])-(LC [Mid-1]-LC L-1]); suk + = Lc [r-1]-LC [Mid]-A [Mid]. x * (Lb [r-1]-lb [Mid]); Suk + = (a [R]. p-(Lb [R]-lb L-1]-t) * (a [R]. x-A [Mid]. x); If (Suk <= k) return true;} */} For (INT I = N; I> = 1; I --) {Suk = 0; R = I; L = find_right (I, 1, I, T); If (L =-1) continue; Mid = f Ind_right (I, 1, I, (t + 1)/2); Suk + = RC [Mid + 1]-RC [I + 1]-A [Mid]. x * (rb [Mid + 1]-Rb [I + 1]); Suk + = A [Mid]. x * (rb [L + 1]-Rb [Mid])-(RC [L + 1]-RC [Mid]); Suk + = (a [l]. p-(rb [l]-Rb [R + 1]-t) * (a [Mid]. x-A [l]. x); If (Suk <= k) return true;/* If (T % 2 = 0) {Suk = 0; Mid = find_right (I, 1, I, (t + 2)/2); Suk + = RC [Mid + 1]-RC [I + 1]-A [Mid]. x * (rb [Mid + 1]-Rb [I + 1]); Suk + = A [Mid]. x * (rb [L + 1]-Rb [Mid])-(RC [L + 1]-RC [Mid]); Suk + = (a [l]. p-(rb [l]-Rb [R + 1]-t) * (a [Mid ]. X-A [l]. x); If (Suk <= k) return true;} */} return false;} int CMP (node A1, node A2) {return a1.x <a2.x ;} int main () {_ int64 sum = 0; while (scanf ("% i64d % i64d", & N, & K )! = EOF) {sum = 0; For (INT I = 1; I <= N; I ++) {scanf ("% i64d % i64d", & A [I]. x, & A [I]. p); sum + = A [I]. p;} Sort (a + 1, A + n + 1, CMP); solve (); _ int64 L = 0; _ int64 r = sum; _ int64 ans = 0; while (L <= r) {_ int64 mid = (L + r)/2; If (is_true (MID) = true) {If (ANS <mid) ans = mid; L = Mid + 1;} else r = mid-1;} printf ("% i64d \ n", ANS );} return 0 ;}