[Luogu] 聪明的质监员
https://www.luogu.org/problemnew/show/P1314
满足单调性
所以,二分W,进行检验
#include <iostream> #include <cstdio> #include <cmath> #include <algorithm> using namespace std; const int N = 2e5 + 10; #define LL long long #define oo 999999999999 #define gc getchar() int n, m; LL s; int W[N], V[N], L[N], R[N]; int sum[N], tot[N]; LL Answer = oo; inline LL read() { LL x = 0; char c = gc; while(c < '0' || c > '9') c = gc; while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = gc; return x; } bool see(int w) { sum[0] = tot[0] = 0; for(int i = 1; i <= n; i ++) { sum[i] = sum[i - 1]; tot[i] = tot[i - 1]; if(W[i] >= w) sum[i] += V[i], ++ tot[i]; } LL ans(0); for(int i = 1; i <= m; i ++) ans += (sum[R[i]] - sum[L[i] - 1]) * (tot[R[i]] - tot[L[i] - 1]); ans = ans - s; Answer = min(abs(ans), Answer); return ans > 0; } int main() { n = read(), m = read(), s = read(); for(int i = 1; i <= n; i ++) W[i] = read(), V[i] = read(); for(int i = 1; i <= m; i ++) L[i] = read(), R[i] = read(); LL l = 0, r = oo; while(l <= r) { LL mid = (l + r) >> 1; if(see(mid)) l = mid + 1;//比标准值大 else r = mid - 1; } cout << Answer; return 0; } /* 5 3 15 1 5 2 5 3 5 4 5 5 5 1 5 2 4 3 3 */