聪明的质监员【题目链接】

有关算法:

二分答案;

但是你只二分答案是不够的,因为你check会炸,所以还要考虑前缀和;

首先假装我们的check已经写好了,main函数:

int main() {
n=read();
m=read();
S=read();
ll maxn=;
for(ll i=; i<=n; i++)
w[i]=read(),v[i]=read(),maxn=max(maxn,w[i]);
for(ll i=; i<=m; i++)
_l[i]=read(),_r[i]=read();
ll l=,r=maxn,ans1=1e17+,ans2=1e17+;
while(l<=r) {
ll mid=l+r>>;
ll ls=check(mid);
if(ls<S) {
ans1=min(ans1,S-ls);
r=mid-;
}
if(ls==S) {
printf("");
return ;
}
if(ls>S) {
ans2=min(ans2,ls-S);
l=mid+;
}
}
printf("%lld",min(ans1,ans2));
return ;
}

输入没有什么可以说的,然后是二分答案,二分答案的话,从0~最大的wi;

二分的标准套路,先计算mid,用check函数判应该往左区间二分还是右区间二分,比较不好想的就是怎么判断往左区间还是右区间二分,这里可以想到,当我们求出的中间值的Y之后,如果发现它比S小,那么如果要找更小的差距,应该让Y的值更大才有可能,那么如果让Y的值更大,我们应该选入更多的矿产,所以我们应该使二分的答案减小,因此r=mid-1;然后这里记录两个答案,ans1,ans2,分别记录的是求得的值小于S的最小差,求得值大于S的最小差(显然等于S时就直接输出不需要再继续循环了);

然后如果没有找到使差为0的W,我们就输出ans1和ans2中较小的一个;

好了讲完了;

并没有讲完啊,我们还莫得讲check函数;

最简单的方法,暴力扫描:

ll check(ll x) {
ll cnt=,sum=,Y=;
for(ll i=; i<=m; i++) {
cnt=;
sum=;
for(ll j=_l[i]; j<=_r[i]; j++) {
if(w[j]>=x) cnt++,sum+=v[j];
}
Y+=(cnt*sum);
}
return Y;
}

然后你会发现你T成这样:

然后经过大佬ych的提醒,我们想到了前缀和:

ll check(ll x) {
ll Y=;
for(int i=;i<=n;i++){
if(w[i]>=x) sum[i]=sum[i-]+v[i],cnt[i]=cnt[i-]+;
else sum[i]=sum[i-],cnt[i]=cnt[i-];
}
for(int i=;i<=m;i++){
Y+=_abs(sum[_r[i]]-sum[_l[i]-])*_abs(cnt[_r[i]]-cnt[_l[i]-]);
}
return Y;
}

sum[i]表示1~i所有点中所有wi>=二分答案的的矿产的v之和,cnt[i]表示1~i以内所有点中所有wi>=二分答案的矿产个数;

然后处理应该很好理解,不再赘述;

然后再一次for循环,对于每个区间,利用维护的前缀和计算sum*cnt,然后相加即为答案;

#include<bits/stdc++.h>
#define ll long long using namespace std; inline ll read() {
ll ans=;
char last=' ',ch=getchar();
while(ch<''||ch>'') last=ch,ch=getchar();
while(ch>=''&&ch<='') ans=(ans<<)+(ans<<)+ch-'',ch=getchar();
if(last=='-') ans=-ans;
return ans;
} ll n,m,w[],v[],S,_l[],_r[],sum[],cnt[]; ll _abs(ll x) {
if(x<) x=-x;
return x;
} ll check(ll x) {
ll Y=;
for(int i=;i<=n;i++){
if(w[i]>=x) sum[i]=sum[i-]+v[i],cnt[i]=cnt[i-]+;
else sum[i]=sum[i-],cnt[i]=cnt[i-];
}
for(int i=;i<=m;i++){
Y+=_abs(sum[_r[i]]-sum[_l[i]-])*_abs(cnt[_r[i]]-cnt[_l[i]-]);
}
return Y;
} int main() {
n=read();
m=read();
S=read();
ll maxn=;
for(ll i=; i<=n; i++)
w[i]=read(),v[i]=read(),maxn=max(maxn,w[i]);
for(ll i=; i<=m; i++)
_l[i]=read(),_r[i]=read();
ll l=,r=maxn,ans1=1e17+,ans2=1e17+;
while(l<=r) {
ll mid=l+r>>;
ll ls=check(mid);
if(ls<S) {
ans1=min(S-ls,ans1);
r=mid-;
}
if(ls==S) {
printf("");
return ;
}
if(ls>S) {
ans2=min(ans2,ls-S);
l=mid+;
}
}
printf("%lld",min(ans1,ans2));
return ;
}

end-

【洛谷p1314】聪明的质监员的更多相关文章

  1. 洛谷P1314 聪明的质监员

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

  2. 洛谷P1314 聪明的质监员 题解

    题目 聪明的质监员 题解 这道题和之前Sabotage G的那道题类似,都是用二分答案求解(这道题还要简单一些,不需要用数学推导二分条件,只需简单判断一下即可). 同时为了降低复杂度,肯定不能用暴力求 ...

  3. 洛谷 P1314 聪明的质监员 —— 二分

    题目:https://www.luogu.org/problemnew/show/P1314 显然就是二分那个标准: 当然不能每个区间从头到尾算答案,所以要先算出每个位置被算了几次: 不知为何自己第一 ...

  4. [NOIP2011] 提高组 洛谷P1314 聪明的质监员

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

  5. 洛谷 P1314 聪明的质监员【二分+前缀和】

    真是zz, 题目很显然是二分W,然后判断,我一开始是用线段树维护当前w[i]>W的个数和v(公式就是区间满足要求的个数*满足要求的v的和),然后T成70 后来想到树状数组差分常数或许会小,于是改 ...

  6. 洛谷——P1314 聪明的质监员

    https://www.luogu.org/problem/show?pid=1314 题目描述 小T 是一名质量监督员,最近负责检验一批矿产的质量.这批矿产共有 n 个矿石,从 1到n 逐一编号,每 ...

  7. 『题解』洛谷P1314 聪明的质监员

    更好的阅读体验 Portal Portal1: Luogu Portal2: LibreOJ Portal3: Vijos Description 小T是一名质量监督员,最近负责检验一批矿产的质量.这 ...

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

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

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

    P1314 聪明的质监员 显然可以二分参数W 统计Y用下前缀和即可. #include<iostream> #include<cstdio> #include<cstri ...

  10. luogu P1314 聪明的质监员 x

    P1314 聪明的质监员(至于为什么选择这个题目,可能是我觉得比较好玩呗) 题目描述 小T 是一名质量监督员,最近负责检验一批矿产的质量.这批矿产共有 n 个矿石,从 1到n 逐一编号,每个矿石都有自 ...

随机推荐

  1. Flask【第8篇】:flask-session组件

    flask-session组件 简介 flask-session是flask框架的session组件,由于原来flask内置session使用签名cookie保存,该组件则将支持session保存到多 ...

  2. java: 列出本机java环境

    java: 列出本机java环境 System.getProperties().list(System.out);

  3. Python---进阶---logging---装饰器打印日志

    #### logging - logging.debug - logging.info - logging.warning - logging.error - logging.critical --- ...

  4. 039:模版结构优化之include标签详解

    引入模版: 有时候一些代码是在许多模版中都用到的.如果我们每次都重复的去拷贝代码那肯定不符合项目的规范.一般我们可以把这些重复性的代码抽取出来,就类似于Python中的函数一样,以后想要使用这些代码的 ...

  5. 1px像素问题(移动端经典问题)

    1.物理像素:移动设备出厂时,不同设备自带的不同像素,也称硬件像素: 逻辑像素:即css中记录的像素 在开发中,为什么移动端CSS里面写了1px,实际上看起来比1px粗:了解设备物理像素和逻辑像素的同 ...

  6. handy源码阅读(四):Channel类

    通道,封装了可以进行epoll的一个fd. struct Channel: private noncopyable { Channel(EventBase* base, int fd, int eve ...

  7. linux运维、架构之路-Kubernetes本地镜像仓库+dashboard部署

    一.部署docker registry            生产环境中我们一般通过搭建本地的私有镜像仓库(docker registry)来拉取镜像. 1.拉取registry镜像 [root@k8 ...

  8. 百度小程序 配置 app.json 文件

    可以通过配置 app.json 文件,设置 SWAN 的界面.路径.多 TAB 等. app.json 配置项列表如下 属性 类型 必填 描述 pages Array.<string> 是 ...

  9. k8s从Harbor拉取启动镜像测试

    登陆harbor [root@k8s-master ~]# docker login 192.168.180.105:1180 Username: admin Password: WARNING! Y ...

  10. 【转】解决ajax跨域问题的5种解决方案

    转自: https://blog.csdn.net/itcats_cn/article/details/82318092   什么是跨域问题?跨域问题来源于JavaScript的"同源策略& ...