题意
传送门 NC 16597
题解
Y
=
∑
i
=
1
m
(
∑
j
1
×
∑
j
v
j
)
,
w
j
≥
W
,
L
i
≤
j
≤
R
i
Y=\sum_{i=1}^{m}(\sum_{j}1\times \sum_{j}v_{j}),w_j\geq W,L_i\leq j\leq R_i
Y=i=1∑m(j∑1×j∑vj),wj≥W,Li≤j≤Ri
Y
Y
Y 随
w
w
w 递增单调不增,故二分参数
w
w
w。预处理前缀和,则
Y
i
Y_i
Yi 的
∑
j
1
\sum_{j}1
∑j1 与
∑
j
v
j
\sum_{j}v_{j}
∑jvj 项可以
O
(
1
)
O(1)
O(1) 内求出。考虑到计算
Y
Y
Y 可能爆
l
o
n
g
l
o
n
g
long\ long
long long,且
S
S
S 范围较小,则
Y
Y
Y 值超出
S
×
2
S\times 2
S×2 时即可停止计算,因为此时
Y
Y
Y 已超过
a
b
s
(
Y
−
S
)
abs(Y-S)
abs(Y−S) 的可能最小值。
#include <bits/stdc++.h>
using namespace std;
#define max(a, b) ((a) > (b) ? (a) : (b))
#define min(a, b) ((a) < (b) ? (a) : (b))
#define maxn 200005
typedef long long ll;
ll n, m, s, limit;
ll w[maxn], v[maxn], l[maxn], r[maxn], num[maxn], sum[maxn];
ll calc(ll x)
{
for (int i = 1; i <= n; i++)
{
num[i] = num[i - 1], sum[i] = sum[i - 1];
if (w[i] >= x) num[i]++, sum[i] += v[i];
}
ll y = 0, s1 = 0, s2 = 0;
for (int i = 1; i <= m; i++)
{
s1 = num[r[i]] - num[l[i] - 1], s2 = sum[r[i]] - sum[l[i]- 1];
if ((y += s1 * s2) > limit) break;
}
return y;
}
int main()
{
scanf("%lld%lld%lld", &n, &m, &s);
for (int i = 1; i <= n; i++) scanf("%lld%lld", w + i, v + i);
for (int i = 1; i <= m; i++) scanf("%lld%lld", l + i, r + i);
limit = s << 1;
ll lb = 0, ub = 1000005;
while (ub - lb > 1)
{
ll mid = (lb + ub) >> 1;
if (calc(mid) - s < 0) ub = mid;
else lb = mid;
}
printf("%lld\n", min(abs(calc(lb) - s), abs(calc(ub) - s)));
return 0;
}