[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 
*/

 

posted @ 2018-03-25 17:57  xayata  阅读(172)  评论(0编辑  收藏  举报