聪明的质监员题解

原题:洛谷P1314

题解
这道题属于典型的二分:W越小,Y越大那么就直接做就完事了呗。注意一下几点:
1.开long long
2.使用前缀和,否则可能会超时

代码

#include <bits/stdc++.h>
using namespace std;
int n, m, w[200005], v[200005], L[200005], R[200005], Max;
int dp1[200005] = {};//dp1表示大于W的数量前缀和
long long dp2[200005] = {}, ans = 0;//dp2表示检验值前缀和
long long s;
long long Y(int W) {
    ans = 0;
    for (int i = 1; i <= n; i++) {
        if (w[i] >= W)
            dp1[i] = dp1[i - 1] + 1, dp2[i] = dp2[i - 1] + v[i];
        else
            dp1[i] = dp1[i - 1], dp2[i] = dp2[i - 1];
    }
    for (int i = 1; i <= m; i++) {
        ans += (dp1[R[i]] - dp1[L[i] - 1]) * (dp2[R[i]] - dp2[L[i] - 1]);
    }
    return ans;
}
int half(int l, int r) {
    if (l == r)
        return l;
    if (l == r - 1) {
        if (abs(Y(l) - s) < abs(Y(r) - s))
            return l;
        return r;
    }
    int mid = (l + r) / 2;
    if (Y(mid) > s)
        return half(mid, r);
    return half(l, mid);
}
int main() {
    cin >> n >> m >> s;
    for (int i = 1; i <= n; i++) {
        cin >> w[i] >> v[i];
        Max = max(Max, w[i]);
    }
    for (int i = 1; i <= m; i++) cin >> L[i] >> R[i];
    int W = half(1, Max);
    printf("%lld", abs(Y(W) - s));
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值