聪明的质监员
P1314 [NOIP2011 提高组] 聪明的质监员 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
- 二分思路
- 当y>s时需要增大w来减小y
- 当y<s时需要减小w来增大y
- 所以y>s or y<s就成为judge函数返回值,用于控制w增大取右边还是减小取左边
- judge函数内计算y值用前缀和的思想,pre_n代表个数,pre_v代表值,对每个区间用乘法计算
// https://www.luogu.com.cn/problem/P1314
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define MAX 200005
ll n, m, pre_n[MAX], pre_v[MAX], v[MAX], w[MAX], ans, r[MAX], l[MAX], s, sum = 0x3f3f3f3f3f3f3f3f, max_w = -1, min_w = 2147483647;
void init()
{
ans = 0;
memset(pre_n, 0, sizeof(pre_n));
memset(pre_v, 0, sizeof(pre_v));
}
bool judge(ll ww)
{
init();
for (ll i = 1; i <= n; i++)
if (w[i] >= ww)
pre_n[i] = pre_n[i - 1] + 1, pre_v[i] = pre_v[i - 1] + v[i];
else
pre_n[i] = pre_n[i - 1], pre_v[i] = pre_v[i - 1];
for (ll i = 1; i <= m; i++)
{
ans += (pre_n[r[i]] - pre_n[l[i] - 1]) * (pre_v[r[i]] - pre_v[l[i] - 1]);
}
sum = min(sum, llabs(ans - s));
return ans > s;
}
void input()
{
cin >> n >> m >> s;
for (ll i = 1; i <= n; i++)
{
scanf("%lld%lld", w + i, v + i);
max_w = max(w[i], max_w);
min_w = min(w[i], min_w);
}
for (int i = 1; i <= m; i++)
{
scanf("%lld%lld", l + i, r + i);
}
}
int main()
{
input();
ll left = min_w - 1, right = max_w + 2;
while (left <= right)
{
ll mid = (left + right) >> 1;
if (judge(mid))
left = mid + 1;
else
right = mid - 1;
}
printf("%lld", sum);
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】