LuoguP1314 聪明的质检员 【二分答案/前缀和】
美丽的题号预示着什么...
描述
小 T 是一名质量监督员,最近负责检验一批矿产的质量。这批矿产共有n个矿石,从1到n逐一编号,每个矿石都有自己的重量wi以及价值vi。检验矿产的流程是:
1、给定m个区间[Li,Ri];
2、选出一个参数W;
3、对于一个区间[Li,Ri],计算矿石在这个区间上的 检验值Yi:

这批矿产的 检验结果Y 为各个区间的检验值之和 。即: Y1+Y2...+Ym
若这批矿产的 检验结果 与所给标准值S相差太多,就需要再去检验另一批矿产。小T不想费时间去检验另一批矿产,所以他想通过调整参数W的值,让 检验结果 尽可能的靠近标准值S,即使得 S-Y 的绝对值最小。请你帮忙求出这个最小值。
格式
输入格式
第一行包含三个整数n,m,S,分别表示矿石的个数、区间的个数和标准值。
接下来的n行,每行2个整数,中间用空格隔开,第i+1行表示i号矿石的重量wi和价值vi 。
接下来的m行,表示区间,每行2个整数,中间用空格隔开,第i+n+1行表示区间[Li,Ri]的两个端点Li和Ri。 注意:不同区间可能重合或相互重叠。
输出格式
输出只有一行,包含一个整数,表示所求的最小值。
样例1
样例输入1
5 3 15
1 5
2 5
3 5
4 5
5 5
1 5
2 4
3 3
样例输出1
10
提示
样例说明:当W选4的时候,三个区间上检验值分别为20、5、0,这批矿产的检验结果为25,此时与标准值S相差最小为10。
对于10%的数据,有1 ≤ n,m ≤ 10;
对于30%的数据,有1 ≤ n,m ≤ 500;
对于50%的数据,有1 ≤ n,m ≤ 5,000;
对于70%的数据,有1 ≤ n,m ≤ 10,000;
对于100%的数据,有1 ≤ n,m ≤ 200,000,0 < wi, vi ≤ 10^6,0 < S ≤ 10^12,1 ≤ Li ≤ Ri ≤ n。
来源
NOIp2011提高组Day2第二题
这道题...题面读了好久(晦涩难懂)
做背包做惯了于是以下及我的代码把数组v与w的意义调换了一下(v为重量,w为价值)
因为参数值W是不固定的,而且坐落在有序的一段区间上(1~max v[i] ),所以我们可以愉快地使用二分答案。
如果我们二分出的这个参数值使得Y较小,说明参数取得有些大,满足的值很少,我们向左移一移。
如果我们二分出的这个参数值使得Y较大,说明参数取得有些小,满足的值很多,我们向右移一移。
根据lyd老师的指引,我们愉快地写出了二分答案的代码
int l=,r=mx;
while(l<r)
{
int mid=(l+r+)>>;
Y=check(mid);
if(Y<s) r=mid-;
else l=mid;
ans=min(ans,abs(s-Y));
}
接下来就是check函数的写法。
由于数据达到了1e6,我们肯定不能暴力计算区间和,前缀和坠吼了。
ll check(int x)
{
ll tmp=;
for(int i=;i<=n;i++)
{
sum[i]=sum[i-];
cnt[i]=cnt[i-];
if(v[i]>=x)
{
sum[i]+=w[i];
cnt[i]++;
}
}
for(int i=;i<=m;i++)
tmp+=(sum[q[i].second]-sum[q[i].first-])*(cnt[q[i].second]-cnt[q[i].first-]);
return tmp;
}
于是我们就愉快地AC了。
code
#include<cstdio>
#include<algorithm>
#include<utility>
#define inf (1LL<<60) using namespace std;
typedef long long ll; int n,m,mx;
int v[],w[];
ll ans=inf,s,Y,sum[],cnt[];
pair<int,int> q[];
/*ll check(int x)
{
ll tmp=0;
for(int i=1;i<=m;i++)
{
int pos=lower_bound(v+1,v+n+1,x)-v;
if(pos>q[i].second) continue;
int cnt=max(pos,q[i].first);
tmp+=(w[q[i].second]-w[cnt-1])*(q[i].second-cnt+1);
}
return tmp;
}*/
ll check(int x)
{
ll tmp=;
for(int i=;i<=n;i++)
{
sum[i]=sum[i-];
cnt[i]=cnt[i-];
if(v[i]>=x)
{
sum[i]+=w[i];
cnt[i]++;
}
}
for(int i=;i<=m;i++)
tmp+=(sum[q[i].second]-sum[q[i].first-])*(cnt[q[i].second]-cnt[q[i].first-]);
return tmp;
}
int main()
{
scanf("%d%d%lld",&n,&m,&s);
for(int i=;i<=n;i++)
scanf("%d%d",&v[i],&w[i]),mx=max(mx,v[i]);
for(int i=;i<=m;i++)
scanf("%d%d",&q[i].first,&q[i].second);
/* sort(a+1,a+n+1,cmp);*/
/* sum[1]=a[1].w;
for(int i=2;i<=n;i++)
sum[i]=sum[i-1]+a[i].w;*/ int l=,r=mx;
while(l<r)
{
int mid=(l+r+)>>;
Y=check(mid);
if(Y<s) r=mid-;
else l=mid;
ans=min(ans,abs(s-Y));
}
printf("%lld",ans);
return ;
}
几个注意事项
§ 虽说没有负数的情况,但是ans初值本身开始也要赋得很大,否则会输出0. (因为这调了很久qaq),ans是long long类型,怎么赋初值?hzwer大神给了一个不错的写法
#define inf (1LL<<60)
§ 开始想排一遍序,然后前缀和直接调用就好了。然而...并没有注意到还有区间下标的限制,还是老实做吧orz!
LuoguP1314 聪明的质检员 【二分答案/前缀和】的更多相关文章
- P1314 聪明的质监员 二分答案
这个题我第一反应是线段树(雾),然后看了一眼题解之后就后悔了...前缀和...然后二分答案,然后就没有然后了. 题干: 小T 是一名质量监督员,最近负责检验一批矿产的质量.这批矿产共有 nnn 个矿石 ...
- NOIP2015聪明的质检员[二分 | 预处理]
背景 NOIP2011 day2 第二题 描述 小T 是一名质量监督员,最近负责检验一批矿产的质量.这批矿产共有 n 个矿石,从 1到n 逐一编号,每个矿石都有自己的重量 wi 以及价值vi .检验矿 ...
- Luogu P1314 聪明的质监员 二分答案
题目链接 Solution 这个范围不是二分就是结论题就是数学题... 然后再看一会差不多就可以看出来有单调性所以就可以确定二分的解法了 二分那个$W$,用前缀和$O(n+m)$的时间来求出对答案的贡 ...
- $Noip2011/Luogu1314$ 聪明的质监员 二分+巧妙前缀和
$Luogu$ $Sol$ 首先$W$一定是某个$w_i$.于是一种暴力方法就出炉了,枚举$W$再计算. 注意到,满足$S-Y$的绝对值最小的$Y$只可能是两种,一种是$<S$的最大的$Y$,一 ...
- Luogu 1314 【NOIP2011】聪明的质检员 (二分)
Luogu 1314 [NOIP2011]聪明的质检员 (二分) Description 小 T 是一名质量监督员,最近负责检验一批矿产的质量.这批矿产共有n个矿石,从 1 到n逐一编号,每个矿石都有 ...
- [NOIP 2011] 聪明的质检员
聪明的质检员 描述 小 T 是一名质量监督员,最近负责检验一批矿产的质量.这批矿产共有n个矿石,从1到n逐一编号,每个矿石都有自己的重量wi以及价值vi.检验矿产的流程是:1.给定m个区间[Li,Ri ...
- [NOIP2011] 聪明的质检员(二分答案)
题目描述 小T 是一名质量监督员,最近负责检验一批矿产的质量.这批矿产共有 n 个矿石,从 1到n 逐一编号,每个矿石都有自己的重量 wi 以及价值vi .检验矿产的流程是: 1 .给定m 个区间[L ...
- Luogu P1314 聪明的质监员(二分+前缀和)
P1314 聪明的质监员 题意 题目描述 小\(T\)是一名质量监督员,最近负责检验一批矿产的质量.这批矿产共有\(n\)个矿石,从\(1\)到\(n\)逐一编号,每个矿石都有自己的重量\(w_i\) ...
- 洛谷 [P1314] 聪明的质检员(NOIP2011 D2T2)
###一道二分答案加前缀和### 题目中已经暗示的很明显了 "尽可能靠近" " 最小值" 本题的主要坑点在于 long long 的使用 ##abs函数不支持l ...
随机推荐
- 一个Tomcat最多支持多少用户的并发?
,也就是说同时支持 另外,在 Java 中每开启一个线程需要耗用 1MB 的 JVM 内存空间用于作为线程栈之用.Tomcat的最大并发数是可以配置的,实际运用中,最大并发数与硬件性能和CPU数量都有 ...
- C# 获得图片的分辨率和大小
double DPI = pictureBox1.Image.HorizontalResolution;//获得分辨率 gisoracle double w = 1.0 * pictureBox1.I ...
- CentOS 6.X配置 NFS以及启动和mount挂载
一.环境介绍: 服务器:centos 192.168.1.225 客户端:centos 192.168.1.226 二.安装: NFS的安装配置:centos 5 : yum -y install n ...
- Android中传递对象的三种方法
Android知识.前端.后端以至于产品和设计都有涉猎,想成为全栈工程师的朋友不要错过! Android中,Activity和Fragment之间传递对象,可以通过将对象序列化并存入Bundle或者I ...
- 【转】c++ 如何批量初始化数组 fill和fill_n函数的应用
http://blog.csdn.net/sunquana/article/details/9153213 一. fill和fill_n函数的应用: fill函数的作用是:将一个区间的元素都赋予val ...
- Windows 上通过本地搭建 Jekyll环境
一 准备Ruby环境 1 我们首先须要安装Ruby.从站点下载Ruby 上下载Ruby最新版和对应的DevKit. 我下载的是Ruby 2.1.4 (x64)和DevKit-mingw64-6 .注意 ...
- SDUTOJ 2475 Power Strings
<pre class="cpp" name="code">#include<iostream> #include<stdio.h& ...
- CDN具体解释(篇二)
还有还有一个问题就是全部的内容都放在同一个地方.假设我们的server在芝加哥,那么美国中西部的人们訪问server的响应时间和用户体验就比香港.德国.南非以及佛罗里达州的用户好.由于那些用户离ser ...
- 奥斯卡·王尔德十大经典语录
10不够真诚是危急的,太真诚则绝对是致命的.--摘自<身为艺术家的评论者> "A little sincerity is a dangerous thing, and a gre ...
- 【计算机视觉】SIFT中LoG和DoG比較
在实际计算时,三种方法计算的金字塔组数noctaves,尺度空间坐标σ,以及每组金字塔内的层数S是一样的.同一时候,如果图像为640*480的标准图像. 金字塔层数: 当中o_min = 0,对于分辨 ...