NC16597 [NOIP2011]聪明的质监员
题目
题目描述
小T
是一名质量监督员,最近负责检验一批矿产的质量。这批矿产共有 个矿石,从 到 逐一编号,每个矿石都有自己的重量 以及价值 。检验矿产的流程是:
1 、给定 个区间 ;
2 、选出一个参数 ;
3 、对于一个区间 ,计算矿石在这个区间上的检验值 :
其中 为矿石编号。
这批矿产的检验结果 为各个区间的检验值之和。即:
若这批矿产的检验结果与所给标准值 相差太多,就需要再去检验另一批矿产。小T
不想费时间去检验另一批矿产,所以他想通过调整参数 的值,让检验结果尽可能的靠近标准值 ,即使得 最小。请你帮忙求出这个最小值。
输入格式
第一行包含三个整数 ,分别表示矿石的个数、区间的个数和标准值。
接下来的 行,每行两个整数,中间用空格隔开,第 行表示 号矿石的重量 和价值 。
接下来的 行,表示区间,每行两个整数,中间用空格隔开,第 行表示区间 的两个端点 和 。注意:不同区间可能重合或相互重叠。
输出格式
一个整数,表示所求的最小值。
样例 #1
样例输入 #1
5 3 15 1 5 2 5 3 5 4 5 5 5 1 5 2 4 3 3
样例输出 #1
10
提示
【输入输出样例说明】
当 选 的时候,三个区间上检验值分别为 ,这批矿产的检验结果为 ,此时与标准值 相差最小为 。
【数据范围】
对于 的数据,有 ;
对于 的数据,有 ;
对于 的数据,有 ;
对于 的数据,有 ;
对于 的数据,有 ,,, 。
题解
知识点:二分。
由 ,发现 随 增大而减小,所以 随 增大而增大,而答案就在 的零点附近,可以二分 ,得到最优的 来求得最优的 。由于答案并非严格零点,因此最终需要对零点两侧都要计算一遍取最合适的值。
然后,预处理出 的前缀和 与 的前缀和 ,能优化复杂度。
于是有 ,得到 返回 的正负情况。
时间复杂度
空间复杂度
代码
#include <bits/stdc++.h> #define ll long long using namespace std; int n, m; ll s; int w[200007], v[200007]; ll cnt[200007], vsum[200007]; ll ans = ~(1LL << 63); struct area { int l, r; }a[200007]; ll check(int mid) { for (int i = 1;i <= n;i++) { cnt[i] = cnt[i - 1] + (w[i] >= mid); vsum[i] = vsum[i - 1] + (w[i] >= mid) * v[i]; } ll y = 0; for (int i = 1;i <= m;i++) { y += (cnt[a[i].r] - cnt[a[i].l - 1]) * (vsum[a[i].r] - vsum[a[i].l - 1]); } ans = min(ans, abs(s - y));///记录最小值,收敛点附近两个点的值刚好能被mid经过 return s - y >= 0; /* check(mid)代表W=mid的s-y 是否>= 0 若是,则W需要变小;若否,则W需要变大 Y随W增大而减少, 但增量未知,而我们要求的是|s-y|而非W, 所以需要记录收敛点(变号点)左右两点的最小值 */ } int main() { std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0); cin >> n >> m >> s; for (int i = 1;i <= n;i++) cin >> w[i] >> v[i]; for (int i = 1;i <= m;i++) cin >> a[i].l >> a[i].r; int l = 1, r = 1e6; while (l <= r) { ///二分W,因为Y(W)单调减,找到s-y的零点附近即可 int mid = l + r >> 1; if (check(mid)) r = mid - 1; else l = mid + 1; } cout << ans << '\n'; return 0; }
本文来自博客园,作者:空白菌,转载请注明原文链接:https://www.cnblogs.com/BlankYang/p/16420758.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧