由于我是直接写的hard版本的,而hard版本和easy版本只有数据范围的差距,所以在此只阐述hard版本的题解(easy版也能过,但是easy的数据范围应该还有其他方法可以偷跑过去)

假设x天可以完成,那么x+1天肯定可以,因为x+1天的第一杯咖啡是没有损耗的(本题中由于每多一天,咖啡效果-1,所以记作孙损耗)

假设x天无法完成,那么x-1天肯定不行,因为x天起码第一杯咖啡是没有损耗的

故此,可看出本题中的天数具有单调性。

那二分得到单调性之后怎么处理呢?

先把n杯咖啡从小到大排序

假设我当前二分的天数是x天,那么我先把前x, 即[n - x + 1, n]最大的咖啡拿过来,然后我往前再拿x杯咖啡

直到当前的[l, r]中有某一个咖啡的大小是大于当前的损耗的,我再次二分找到这一个咖啡

假设是第t杯,我只用加上[t + 1, r] - 损耗,然后我就不用再往前找咖啡了,因为必定是大于之后的损耗的

那么我把现在的咖啡的效果累加减去损耗后要是大于m,即二分可行,否则二分不行

这里,对于[l, r]的咖啡的值由于只涉及查询不涉及更新,所以我用了前缀和维护

二分的效率是logN * logN,应该还没有N大,所以可以看做是O(N)(应该吧)

#include<bits/stdc++.h>
#define LL long long
using namespace std;
const int MAXN = 2e5 + 10;LL cs[MAXN], lei[MAXN];
int n, m;bool check(int x)
{LL sum = 0, t = 0;int r = n, l = n - x + 1;while(1){int ans = -1;int tl = l, tr = r;while(tl <= tr){int mid = (tl + tr) >> 1;if(cs[mid] < t){ans = mid;tl = mid + 1;}elsetr = mid - 1;}if(ans == -1){sum += lei[r] - lei[l - 1] - (r - l + 1) * t;r = l - 1;l = (r - x + 1) >= 1 ? (r - x + 1) : 1;}else{if(ans == r){sum += 0;break;}else{sum += lei[r] - lei[ans] - (r - ans) * t;break;}}t ++;if(r < 1)break;}if(sum >= m)return 1;elsereturn 0;
}
int main()
{LL maxx = 0;LL sum = 0;scanf("%d %d", &n, &m);for(int i = 1; i <= n; i ++){scanf("%d", &cs[i]);sum += cs[i];maxx = max (maxx, cs[i]);}if(sum < m){cout << -1 << endl;return 0;}sort (cs + 1, cs + n + 1);for(int i = 1; i <= n; i ++)lei[i] = lei[i - 1] + cs[i];//build(1, n, 1);//cout << 1 << endl;int l = 1, r = n, ans;while(l <= r){int mid = (l + r) >> 1;//cout << "! " << mid << endl;if(check(mid)){ans = mid;r = mid - 1;}elsel = mid + 1;}printf("%d", ans);return 0;
}

Codeforces Round #540 (Div. 3) Coffee and Coursework相关推荐

  1. Codeforces Round #540 (Div. 3) A,B,C,D2,E,F1

    A. Water Buying 链接:http://codeforces.com/contest/1118/problem/A 实现代码: #include<bits/stdc++.h> ...

  2. Codeforces Round #540 (Div. 3)(部分题解)

    链接:http://codeforces.com/contest/1118 来源:Codeforces 文章目录 A. Water Buying B. Tanya and Candies(前缀和) D ...

  3. Codeforces Round #540 (Div. 3) D. Coffee and Coursework 二分

    题解 题目大意,有若干杯咖啡,每杯咖啡有一个收益a[i],不限制每天喝多少杯,但是每天的第k杯收益会减少k-1,问总收益大于n的所需最少天数. 使用二分答案求解,每次喝肯定是挑剩余最大的去喝,chec ...

  4. Codeforces Round #540 (Div. 3)--A. Water Buying(简单思维题-有点坑)

    A. Water Buying 题目链接http://codeforces.com/problemset/problem/1118/A time limit per test:1 second mem ...

  5. 【Codeforces Round #540 (Div. 3)】 A B C D1 D2 E F1

    A 题意 给你一升水和两升水的价格 问你怎么买便宜 做法 模拟即可 #include <cstdio> #include <cstring> #include <iost ...

  6. Codeforces Round #506 (Div. 3)

    Codeforces Round #506 (Div. 3) 实习期间事不多,对div3 面向题解和数据编程了一波 A. Many Equal Substrings 题目链接 A题就是找后缀和前缀重合 ...

  7. Codeforces Round #563 (Div. 2)/CF1174

    Codeforces Round #563 (Div. 2)/CF1174 CF1174A Ehab Fails to Be Thanos 其实就是要\(\sum\limits_{i=1}^n a_i ...

  8. 构造 Codeforces Round #302 (Div. 2) B Sea and Islands

    题目传送门 1 /* 2 题意:在n^n的海洋里是否有k块陆地 3 构造算法:按奇偶性来判断,k小于等于所有点数的一半,交叉输出L/S 4 输出完k个L后,之后全部输出S:) 5 5 10 的例子可以 ...

  9. Codeforces Round #696 (Div. 2) (A ~ E)超高质量题解(每日训练 Day.16 )

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 Codeforces Round #696 (Div. 2) (A ~ E)超高质量题解 比赛链接:h ...

最新文章

  1. Java合并两个int数组合并_Java中如何把两个数组合并为一个
  2. Foundation ActionScript 3.0.With Flash CS3 And Flex ..
  3. flash与动画:打字动画(2)
  4. K8S部署工具:KubeOperator集群部署
  5. 一起谈.NET技术,Visual Studio与C#编程十个实用技巧
  6. k8s 命令 重启_k8s 常用命令
  7. 「作文素材详解」写作必知篇:语言优美不是作文第一要求
  8. cstring和string头文件
  9. React传递参数的多种方式
  10. 用计算机怎么发邮件,怎么用qq邮箱发文件-你必须要学会的电脑操作——邮件收发...
  11. python异步编程 图书_Python异步编程介绍
  12. 华为管理学案例分析_华为案例分析——管理学作业.ppt
  13. 路由器更换wan口及vlan配置
  14. 复旦大学与国网上海共建“电力大数据实验室”
  15. 公寓宽带服务器无响应,学生宿舍公寓网络建设项目需求分析报告文档(8页)-原创力文档...
  16. QT实现简单的上位机软件
  17. Java List 多维度排序 jdk8
  18. 关于音视频的一些知识(demux、filter等)
  19. Redis Lua拓展及使用示例
  20. 【bzoj4826】影魔

热门文章

  1. 什么是permit-inside功能
  2. 云计算系统体系架构介绍
  3. Visual studio未能正确加载“Microsoft.VisualStudio.Editor.Implementation.EditorPackage”包等问题解决
  4. (三)mmclassification图像分类——模型训练
  5. 电脑搜不到wifi?新换的路由器
  6. bzoj 3007 拯救小云公主
  7. 洛谷 P4408 [NOI2003] 逃学的小孩(树的直径)
  8. 学习 《模型思维》-斯科特·佩奇 笔记 9.26
  9. 宝塔linux面板命令大全
  10. 牛客网 石家庄铁道大学新生选拔赛