美丽的题号预示着什么...

描述

小 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 聪明的质检员 【二分答案/前缀和】的更多相关文章

  1. P1314 聪明的质监员 二分答案

    这个题我第一反应是线段树(雾),然后看了一眼题解之后就后悔了...前缀和...然后二分答案,然后就没有然后了. 题干: 小T 是一名质量监督员,最近负责检验一批矿产的质量.这批矿产共有 nnn 个矿石 ...

  2. NOIP2015聪明的质检员[二分 | 预处理]

    背景 NOIP2011 day2 第二题 描述 小T 是一名质量监督员,最近负责检验一批矿产的质量.这批矿产共有 n 个矿石,从 1到n 逐一编号,每个矿石都有自己的重量 wi 以及价值vi .检验矿 ...

  3. Luogu P1314 聪明的质监员 二分答案

    题目链接 Solution 这个范围不是二分就是结论题就是数学题... 然后再看一会差不多就可以看出来有单调性所以就可以确定二分的解法了 二分那个$W$,用前缀和$O(n+m)$的时间来求出对答案的贡 ...

  4. $Noip2011/Luogu1314$ 聪明的质监员 二分+巧妙前缀和

    $Luogu$ $Sol$ 首先$W$一定是某个$w_i$.于是一种暴力方法就出炉了,枚举$W$再计算. 注意到,满足$S-Y$的绝对值最小的$Y$只可能是两种,一种是$<S$的最大的$Y$,一 ...

  5. Luogu 1314 【NOIP2011】聪明的质检员 (二分)

    Luogu 1314 [NOIP2011]聪明的质检员 (二分) Description 小 T 是一名质量监督员,最近负责检验一批矿产的质量.这批矿产共有n个矿石,从 1 到n逐一编号,每个矿石都有 ...

  6. [NOIP 2011] 聪明的质检员

    聪明的质检员 描述 小 T 是一名质量监督员,最近负责检验一批矿产的质量.这批矿产共有n个矿石,从1到n逐一编号,每个矿石都有自己的重量wi以及价值vi.检验矿产的流程是:1.给定m个区间[Li,Ri ...

  7. [NOIP2011] 聪明的质检员(二分答案)

    题目描述 小T 是一名质量监督员,最近负责检验一批矿产的质量.这批矿产共有 n 个矿石,从 1到n 逐一编号,每个矿石都有自己的重量 wi 以及价值vi .检验矿产的流程是: 1 .给定m 个区间[L ...

  8. Luogu P1314 聪明的质监员(二分+前缀和)

    P1314 聪明的质监员 题意 题目描述 小\(T\)是一名质量监督员,最近负责检验一批矿产的质量.这批矿产共有\(n\)个矿石,从\(1\)到\(n\)逐一编号,每个矿石都有自己的重量\(w_i\) ...

  9. 洛谷 [P1314] 聪明的质检员(NOIP2011 D2T2)

    ###一道二分答案加前缀和### 题目中已经暗示的很明显了 "尽可能靠近" " 最小值" 本题的主要坑点在于 long long 的使用 ##abs函数不支持l ...

随机推荐

  1. 通过XMLHttpRequest,ActiveXObject实现ajax请求

    今天学习了原生的ajax请求.我将涉及到的ajax请求方法封装成了一个对象: var xhr={     getXHR:function(){         var XHR = null;      ...

  2. asterisk 问题

    Q:SIP可以呼通,但听不到声音A:一般是NAT问题造成.如果Asterisk处在NAT的后面,则Asterisk的配置如下: ------------------------------------ ...

  3. 收集的一些Redis操作技巧教程

    redis(1).redis入门 redis(2).redis数据类型 redis(3).基于jedis.spring-data-redis 连接操作redis redis(4).基于redis 构建 ...

  4. MySQL中的数据类型的长度范围和显示宽度(转)

    长度范围是随数据类型就已经是固定的值,而显示宽度与长度范围无关. 以下是每个整数类型的存储和范围(来自MySQL手册) 类型 字节 最小值 最大值 (带符号的/无符号的) (带符号的/无符号的) TI ...

  5. eclipse发布项目到tomcat部署目录

    1.在eclipse下建立Dynamic Web Project工程zhgy,在使用eclipse中new一个tomcat,通过启动该tomcat来发布Dynamic Web Project的时候,其 ...

  6. GreenDao数据库的升级

    应用使用了GreenDao数据库,在版本升级的时候需要更改dao的字段,新增.修改.删除字段操作,如果直接删除原来的表的话那用户原来的一些数据就没有了,所以在更新数据库的时候需要做一次封装,把原来的数 ...

  7. [BLE--Physical Layer]

    简述 BLE的物理层,可能做IC或板极硬件RF測试的会比較关注. 是偏硬件层面的. 频率带宽和信道分配 BLE工作于2.4 GHz ISM频段2400-2483.5 MHz,ISM频段是公用的,不须要 ...

  8. 2003 -Can't connection to mysql server on | navicat for mysql Access denied for user 'root'@''ip'(using password :yes)

    用本机windows上的Navicat for mysql链接虚拟机Linux的mysql数据库时,第一次连接的时候报的错误是 2003 -Can't connection to mysql serv ...

  9. python的线程thread笔记

    python的线程是用thread和threading来实现的.其中利用threading会更好,因为thread没有线程保护,当主线程退出了之后,子线程也会被强行退出.threading支持守护线程 ...

  10. How to get service execuable path

    Some time we need to get specific service path and then do something you want. there are 2 way to ge ...