stone 质检员 (二分)

来源:互联网 发布:python黑客 渗透技术 编辑:程序博客网 时间:2024/04/28 04:23

stone 质检员

10.30

我们可以很容易的发现,随着W 的增加,Y 是单调减小的,
所以说我们可以用类似于二分的方法求出最接近标准值的W,每
次尝试可以在O(n)的时间计算出Y,所以总复杂度O(nlogn)

#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>#define LL long long#define N 200010using namespace std;int n, m, lf, rg, w[N];LL val[N], sum[N], num[N], S, ans, res;struct ask{    int l, r;}q[N];template <class T> inline void read(T &res){    static char ch; int flag=1;    while( (ch = getchar() ) > '9' || ch < '0');    if(ch == '-') flag = -1;    res = ch - 48;    while(( ch = getchar() ) >= '0' && ch <= '9')    res = (res<<1) + (res<<3) + ch - 48;    res = res * flag;}LL check(int x){    for(register int i=1; i<=n; i++){        sum[i] = sum[i-1] + val[i] * (w[i] >= x);        num[i] = num[i-1] + (w[i] >= x);    }    ans = 0;    for(register int i=1; i<=m; i++){        ans += (sum[q[i].r] - sum[q[i].l-1]) * (num[q[i].r] - num[q[i].l-1]);    }    return ans;}int main(){    scanf("%d %d %lld", &n, &m, &S);    res = S;    for(register int i=1; i<=n; i++){        read( w[i] ), read( val[i] );        rg = max(rg, w[i]);    }    for(register int i=1; i<=m; i++){        read( q[i].l ), read( q[i].r );    }    while(lf < rg){        int mid = (lf + rg) >> 1;        if(check( mid ) > S) res = min(res, abs(ans - S)), lf = mid+1;        else res = min(res, abs(ans - S)), rg = mid-1;    }    printf("%lld\n", res);}