首页 > 其他分享 >[题解] [NOIP2011] 聪明的质检员

[题解] [NOIP2011] 聪明的质检员

时间:2024-04-12 16:55:53浏览次数:25  
标签:NOIP2011 int 题解 leq 质检员 MAXN w1 区间 include

[NOIP2011] 聪明的质监员

题目描述

小T 是一名质量监督员,最近负责检验一批矿产的质量。这批矿产共有 \(n\) 个矿石,从 \(1\) 到 \(n\) 逐一编号,每个矿石都有自己的重量 \(w_i\) 以及价值 \(v_i\) 。检验矿产的流程是:

  1. 给定 \(m\) 个区间 \([l_i, r_i]\) ;
  2. 选出一个参数 \(W\) ;
  3. 对于一个区间 \([l_i, r_i]\) ,计算矿石在这个区间上的检验值 \(y_i\):

\(y_i = \displaystyle \sum^{r_i}_{j = l_i}{[w_j\geq W]} \times \displaystyle \sum^{r_i}_{j = l_i}{[w_j\geq W]}v_i\)
其中 \(j\) 为矿石编号。

这批矿产的检验结果 \(y\) 为各个区间的检验值之和。即: \(\displaystyle \sum^{m}_{i = 1}{y_i}\)

若这批矿产的检验结果与所给标准值 \(s\) 相差太多,就需要再去检验另一批矿产。小T 不想费时间去检验另一批矿产,所以他想通过调整参数 \(W\) 的值,让检验结果尽可能的靠近标准值 \(s\) ,即使得 \(∣s−y∣\) 最小。请你帮忙求出这个最小值。

输入格式

第一行包含三个整数 \(n,m,s\) ,分别表示矿石的个数、区间的个数和标准值。

接下来的 \(n\) 行,每行两个整数,中间用空格隔开,第 \(i+1\) 行表示 \(i\) 号矿石的重量 \(w_i\) 和价值 \(v_i\) 。

接下来的 \(m\) 行,表示区间,每行两个整数,中间用空格隔开,第 \(i+n+1\) 行表示区间 \([l_i, r_i]\) 的两个端点 \(l_i\) 和 \(r_i\) 。注意:不同区间可能重合或相互重叠。

输出格式

一个整数,表示所求的最小值。

数据范围

对于 \(100\%\) 的数据,有 \(1 \leq n, m \leq 200,000, 0 < w_i, v_i \leq 10^6, 0 < s \leq 10^{12}, 1 \leq l_i \leq r_i \leq n\) 。

题解

显然,选取的 \(W\) 越大,被选中的数就更少, \(y\) 就越小。不难看出, \(|y - s|\) 关于 \(W\) 是先降再升的单峰函数,分界点是 \(y = s\)。因此我们可以通过二分 \(W\) 的值来寻找最优解。

下面考虑验证。对于一个已经确定的 \(W\) ,每一段区间的测量值都是确定的,不存在策略的差异。因此只需要对每一个区间求测量值再求和即可。因为测量值为区间内符合条件的矿产的数目和 \(\times\) 符合条件的矿产的价值和,需要分别对两个目标求和,采用两个前缀和维护即可。

注意二分的条件。

AC代码

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <string>
#include <stack>
#include <queue>
#define int long long
using namespace std;

const int MAXN = 2e5 + 3;

int n, m, s;
int w[MAXN], v[MAXN], l[MAXN], r[MAXN];

inline int check(int x) {
    int ans = 0;
    int num[MAXN], sum[MAXN];
    for (int i = 0; i <= n; i++) sum[i] = num[i] = 0;
    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];
        }
    }
    for (int i = 1; i <= m; i++) {
        ans += (num[r[i]] - num[l[i] - 1]) * (sum[r[i]] - sum[l[i] - 1]);
    }
    return ans;
}

int w1[MAXN];

signed main() {
    cin >> n >> m >> s;
    for (int i = 1; i <= n; i++) {
        cin >> w[i] >> v[i];
        w1[i] = w[i];
    }
    for (int i = 1; i <= m; i++) {
        cin >> l[i] >> r[i];
    }
    sort(w1 + 1, w1 + 1 + n);
    int nl = 1, nr = n, mid;
    while (nl <= nr) {
        mid = (nl + nr) >> 1;
        if (check(w1[mid]) > s) nl = mid + 1;
        else nr = mid - 1;
    }
    int ans = min(abs(check(w1[mid]) - s), min(abs(check(w1[nl]) - s), abs(s - check(w1[nr]))));
    cout << ans << '\n';
    return 0;
}

标签:NOIP2011,int,题解,leq,质检员,MAXN,w1,区间,include
From: https://www.cnblogs.com/Floyd3265/p/18131647

相关文章

  • Qt程序加载Qt platform plugin 'xcb' 出错问题解决
    1.Qt程序运行环境ubuntu16.04Qt5.12.3Qt可执行程序编译后运行Qt可执行程序后出现报错报错内容:qt.qpa.plugin:CouldnotloadtheQtplatformplugin"xcb"in""eventhoughitwasfound.ThisapplicationfailedtostartbecausenoQtplatformplugincouldbe......
  • [题解][2022江西省程序设计竞赛] Graphic Game
    题目描述Cirno被推荐了一个游戏,她决定今天和大妖精一起玩。最初,有一个包含2×n个顶点和m条边的图。在每一轮中,Cirno和大妖精都必须选择一个不同的顶点。所选顶点的度数必须相同。然后,Cirno和大妖精将从图中移除它们。现在Cirno想知道是否有办法从给定的图中移除所有顶点。如果......
  • windows MySQL报错Packet for query is too large问题解决
    1、报错Cause:com.mysql.cj.jdbc.exceptions.PacketTooBigException:Packetforqueryistoolarge(11,792,709>4,194,304).Youcanchangethisvalueontheserverbysettingthe'max_allowed_packet'variable.出现问题的原因:批量插入数据量过大MySQL根据配置......
  • Cunning Gena 题解
    \(\texttt{ProblemLink}\)简要题意翻译很清楚。思路记\(x_i\)表示第\(i\)个人的花费,\(s_i\)表示第\(i\)个人做题集合,\(k_i\)表示第\(i\)个人需要的显示器。\(m\le20\)且不是计数,考虑dp,发现确实可以做。可以设\(f_i\)表示做题集合为\(i\)时最小花费。易......
  • [题解][2022江西省程序设计大赛] A Game of Taking Numbers
    题目描述rqdmap和他的小女友正在玩一个游戏。有n个正整数。这两个人轮流取数字。为了显示他的绅士风度,rqdmap要求他的小女友先取数字。每当rqdmap的小女友可以选择剩下的数字中的任意一个来拿走(记为x),rqdmap需要从剩下的数字中选择一个数字(记为y),并且满足以下两个条件中的至少一个......
  • 文件下载时中文文件名乱码及链接失效问题解决
    问题:报错提示11-Apr-202415:38:43.792信息[Catalina-utility-2]org.apache.catalina.startup.HostConfig.deployDirectoryWeb应用程序目录[G:\开发工作用软件\Java开发用\apache-tomcat-10.1.7\webapps\manager]的部署已在[293]毫秒内完成11-Apr-202415:38:44.573信息......
  • 题解 P10314【[SHUPC 2024] 函数】
    注意到:\[f(x)=\lfloorx\rfloor,\qquad(x\notin\N)\]代码:intT;doublex;cout<<fixed<<setprecision(12);for(cin>>T;T;--T){cin>>x;cout<<floor(x)<<endl;}感觉说明不够过不了审,于是简单说一下正确性:由诱导公式\(\c......
  • [题解] [洛谷P1404] 平均数
    洛谷P1404平均数题目描述给一个长度为\(n\)的数列,我们需要找出该数列的一个子串,使得子串平均数最大化,并且子串长度\(\geqm\)。输入格式第一行两个整数\(n\)和\(m\)。接下来\(n\)行,每行一个整数\(a_i\),表示序列第\(i\)个数字。输出格式一个整数,表示最大平均数......
  • [题解] <NOIP2017> 时间复杂度
    [题解]NOIP2017时间复杂度题目描述小明正在学习一种新的编程语言A++,刚学会循环语句的他激动地写了好多程序并给出了他自己算出的时间复杂度,可他的编程老师实在不想一个一个检查小明的程序,于是你的机会来啦!下面请你编写程序来判断小明对他的每个程序给出的时间复杂度是否正......
  • CF617E XOR and Favorite Number 题解
    想了好久才明白zz来源?:莫队题单题目大意给定一个长度为\(n\)的序列\(a\),然后再给一个数字\(k\),再给出\(m\)组询问,每组询问给出一个区间,求这个区间里面有多少个子区间的异或值为\(k\)。\(1\len,m\le10^5\)\(0\lek,a_i\le10^6\)\(1\lel_i,r_i\len\)题......