原题:洛谷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;
}