题目传送门

这道题一开始我还以为是贪心,sort一遍直接取中点然后求最优值。

但写了之后才发现错误,设置的谷仓只要是一段区间的中点即可。这段区间的两端一定是两片谷田。

所以枚举区间的左端点,二分右端点,但问题是如何O(1)判断?

设sumi表示1~i点的和。

L~R区间所需要的费用分成两段来求。

一段为L~mid-1,一段为mid+1~R。

L~mid-1=a[mid]*(mid-l)-(sum[k-1]-sum[l-1]);

mid+1~R=sum[r]-sum[k]-a[k]*(r-k);

两者相加即为这段区间的费用总和。

code:

#include <cstdio>
#include <algorithm>
using namespace std; int read()
{
char c;while(c=getchar(),c<''||c>'');int x=c-'';
while(c=getchar(),c>=''&&c<='')x=x*+c-'';
return x;
} int abs(int x){return x>?x:-x;} const int MAXN=; int R,L,a[MAXN],i,ans;
long long B,sum[MAXN]; int find(int l,int r)
{
long long w=,k=l+r+>>;
w=a[k]*(k-l)-(sum[k-]-sum[l-])+sum[r]-sum[k]-a[k]*(r-k);
return w<=B;
} int check(int x)
{
int l=x,r=R,mid,tot;
while(l<=r){
mid=l+r>>;
if(find(x,mid))l=mid+,tot=mid;
else r=mid-;
}
return tot-x+;
} int main()
{
// freopen("x.txt","r",stdin);
R=read(),L=read();scanf("%lld",&B);
for(i=;i<=R;i++)a[i]=read(),sum[i]=sum[i-]+a[i];
for(i=;i<=R;i++){
ans=max(ans,check(i));
}
printf("%d",ans);
return ;
}

最新文章

  1. JS trim
  2. curl 传递用户session
  3. gulp 使用介绍
  4. Python与C++结构体交互
  5. 为什么使用ConcurrentHashMap
  6. Open vSwitch使用案例扩展实验
  7. QTP11.00安装+破解详细教程
  8. 将从网上下载下来的javaweb项目继续配置
  9. python爬爬(网友提供学习)
  10. 014 一对多关联映射 单向(one-to-many)
  11. 阿里云OSS存储
  12. 解决在SecurecCRT登录后,发现方向键、backspace(退格键)、delete(删除键)为乱码的问题
  13. Linux内核入门到放弃-时间管理-《深入Linux内核架构》笔记
  14. mybatis 动态sql和参数
  15. c++构造函数成员初始化中赋值和初始化列表两种方式的区别
  16. 【阿里八八】团队Alpha博客链接目录
  17. 文件缓冲区在fork后复制
  18. Running a jupyter notebook server
  19. Array常用函数收藏
  20. 【BZOJ1051】[HAOI2006]受欢迎的牛

热门文章

  1. sparsity and density
  2. sublime text html5开发学习 插件篇记录
  3. 学习WebSocket一(WebSocket初识)
  4. Django 创建模型 激活模型 简单的使用模型
  5. Could not publish to the server. null argument:
  6. 【Hankson 的趣味题】
  7. HDU 6395 Sequence 【矩阵快速幂 &amp;&amp; 暴力】
  8. CF#538(div2) B. Yet Another Array Partitioning Task 【YY】
  9. tensorflow训练代码
  10. Linux tmux 使用指南