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 ...
随机推荐
- Mysql 数据库允许远程连接 服务器连接错误 Host 'XXX' is not allowed to connect to this MySQL server
如果连接数据库的时候出现这个问题 Host 'XXX' is not allowed to connect to this MySQL server 说明 Mysql数据库 不允许远程连接, 需要修改 ...
- 30分钟学会如何使用Shiro(转)
本文转自http://www.cnblogs.com/learnhow/p/5694876.html 感谢作者 本篇内容大多总结自张开涛的<跟我学Shiro>原文地址:http://jin ...
- Oracle 行转列小结
近期在工作中.对行转列进行了应用,在此做一个简单的小结. 转换步骤例如以下: 1.创建表结构 CREATE TABLE RowToCol ( ID NUMBER(10) not null, U ...
- 信号量学习 & 共享内存同步
刚刚这篇文章学习了共享内存:http://www.cnblogs.com/charlesblc/p/6142139.html 里面也提到了共享内存,自己不进行同步,需要其他手段比如信号量来进行.那么现 ...
- php 获取TZ时间格式
php将时间格式化成T Z的方法 gmdate("c") 这个函数的用法,学会了吧!!! <?php var_dump(gmdate("c")); ini ...
- Working with Validators and Messages in AngularJS
原文:http://odetocode.com/blogs/scott/archive/2014/10/16/working-with-validators-and-messages-in-angul ...
- hdu 3549 Flow Problem(最大流模板题)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3549 Problem Description Network flow is a well-known ...
- ldd
ldd命令用于判断某个可执行的 binary 档案含有什么动态函式库 [diego@localhost ~/work/branch_dispatch_201511/rtqa_center/source ...
- 错误 1 无法将程序集“NBear.Data.dll”复制到文件“D:\newbpm\bpm\SureBpm\Bin\NBear.Data.dll”。无法将“D:\newbpm\bpm\SureSoft.WebServiceBaseLib\bin\Debug\NBear.Data.dll”添加到网站。 无法添加文件“Bin\NBear.Data.dll”。 拒绝访问。 D:\..
错误 1 无法将程序集“NBear.Data.dll”复制到文件“D:\newbpm\bpm\SureBpm\Bin\NBear.Data.dll”.无法将“D:\newbpm\bpm\SureSof ...
- 2016/2/26 jQuery的技术 1,安装 2,语法选择器$ 事件触发 3,常用jQuery函数
在<网页制作Dreamweaver(悬浮动态分层导航)>中,运用到了jQuery的技术,轻松实现了菜单的下拉.显示.隐藏的效果,不必再用样式表一点点地修改,省去了很多麻烦,那么jQuery ...