Luogu P1314 [NOIP2011 提高组] 聪明的质监员
题意#
题目描述#
- 给定个物品,给定每个物品的 重量 和 价值
- 给定一个标准值 以及一个参数
- 质检员每次会抽取个区间,每次的抽检结果为
- 求出
数据范围#
, ,
SOLUTION#
当 的时候, 当 的时候, 我们想让 尽可能的逼近 对于参数,当越大,越小
因此本题具有单调性。 考虑二分 使得 尽可能的逼近 即可
AC_CODE_1#
#include <bits/stdc++.h>
#define LL long long
using namespace std;
const int N = 2e5 + 10;
int n, m, l = INF, r = -INF;
LL s; // 不开 long long 见祖宗 | =^_^= |
int L[N], R[N];
int w[N], v[N];
LL p1[N], p2[N];
LL chk(int x) {
for(int i = 1; i <= n; i ++ ) {
p1[i] = p1[i - 1]; p2[i] = p2[i - 1];
if(w[i] >= x) {
p1[i] += v[i];
p2[i] ++;
}
}
// printf("\n%d\n", x);
LL ANS = 0;
rep(i, 1, m) {
// printf("> %d %d %lld %lld\n",L[i], R[i], (p1[R[i]] - p1[L[i] - 1]) , (p2[R[i]] - p2[L[i] - 1]));
ANS += (p1[R[i]] - p1[L[i] - 1]) * (p2[R[i]] - p2[L[i] - 1]);
}
return ANS;
}
inline void solve() {
read(n); read(m); read(s);
rep(i, 1, n) {
read(w[i]); read(v[i]);
l = min(l, w[i]); r = max(r, w[i]);
}
rep(i, 1, m) {
read(L[i]); read(R[i]);
}
l --, r ++;
LL ans = INFF;
while(l <= r) { // 由于 l = mid + 1, r = mid - 1 因此while循环里面的条件应该是 l <= r
int mid = l + r >> 1;
LL res = chk(mid);
if(res >= s) l = mid + 1; // 如果结果 y > s 我们就让 w 大一点 这样 y就会小一点更逼近 s
else r = mid - 1; //同理
ans = min(ans, abs(res - s));
// printf("> %d %lld\n", mid, res);
}
printf("%lld\n", ans);
}
signed main()
{
// freopen("in.txt", "r", stdin);
solve();
return 0;
}
AC_CODE_2#
//倍增写法
#include <cstdio>
#include <iostream>
#define LL long long
const int N = 2e5 + 10;
int n, m, ans = 1; LL s;
int w[N], v[N], L[N], R[N]; LL s1[N], s2[N];
inline LL chk(int W) {
for(int i = 1; i <= n; ++ i) {
s1[i] = w[i] >= W ? s1[i - 1] + 1 : s1[i - 1];
s2[i] = w[i] >= W ? s2[i - 1] + v[i] : s2[i - 1];
}
LL res = 0;
for(int i = 1; i <= m; ++ i ) {
res += (s1[R[i]] - s1[L[i] - 1]) * (s2[R[i]] - s2[L[i] - 1]);
}
return res;
}
int main() {
scanf("%d%d%lld", &n, &m, &s);
for(int i = 1; i <= n; i ++ ) scanf("%d%d", &w[i], &v[i]);
for(int i = 1; i <= m; i ++ ) scanf("%d%d", &L[i], &R[i]);
for(int i = 17; i >= 0; -- i) {
ans += chk(ans + (1 << i)) >= s ? (1 << i) : 0;
}
printf("%lld\n", std::min(chk(ans) - s, s - chk(ans + 1)));
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现