@description@

n 个竹子,第 i 个竹子初始高度 hi,在每天结束时将长高 ai。

一共 m 天,每天可以砍伐 k 次,可以多次砍伐同一个竹子。如果砍伐的竹子当前高度 h,则砍后变为 max(0, h - p)。

问 m 天之后最高的竹子的高度最小是多少。

原题传送门。

@solution@

考虑第 i 个竹子如果在第 j 天被砍了 \(c_{i,j}\) 次,则最后剩下的高度应为:

\[\max\{h_i + m\times a_i - \sum_{k=1}^{m}c_{i,k}, \ \max_{j=1}^{m}\{(m-j+1)\times a_i - \sum_{k=j+1}^{m}c_{i,k}\}\}
\]

根据砍伐的定义,这是易证的。

我们不妨二分答案 x,前面包含 hi 的式子暴力 O(n) 判断。后面的式子如果暴力判断是 O(nm) 的复杂度。

注意到 k 很小,也就是说总的砍伐数量只有 O(mk) 次,远远小于 O(nm)。

我们不妨只记录对于每棵竹子而言的有效砍伐,使用 m 个队列从后往前进行模拟,就可以做到 O(mk + n) 的判断时间复杂度。

总时间复杂度 O((mk + n)log A)。

@accepted code@

#include <queue>
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std; typedef long long ll;
typedef pair<int, int> pii;
#define fi first
#define se second
#define mp make_pair const int MAXM = 5000;
const int MAXN = 100000; int n, m, k;
ll a[MAXN + 5], h[MAXN + 5], p;
queue<pii>que[MAXM + 5];
bool check(ll x) {
for(int i=1;i<=m;i++) {
while( !que[i].empty() )
que[i].pop();
} for(int i=1;i<=n;i++) {
ll s = x / a[i] + 1;
if( s <= m ) que[s].push(mp(i, 0));
} for(int i=1,c=0;i<=m;i++,c+=k) {
while( !que[i].empty() ) {
if( c ) c--; else return false; pii f = que[i].front(); que[i].pop(); f.se++;
ll s = (f.se*p + x) / a[f.fi] + 1;
if( s <= m ) que[s].push(f);
}
} ll s = 0;
for(int i=1;i<=n;i++)
s += (max(a[i]*m + h[i] - x, 0LL) + p - 1) / p;
return s <= m*k;
} int main() {
scanf("%d%d%d%lld", &n, &m, &k, &p);
for(int i=1;i<=n;i++) scanf("%lld%lld", &h[i], &a[i]); ll le = 0, ri = 0;
for(int i=1;i<=n;i++)
ri = max(ri, h[i] + m*a[i]); while( le < ri ) {
ll mid = (le + ri) >> 1;
if( check(mid) ) ri = mid;
else le = mid + 1;
}
printf("%lld\n", ri);
}

@details@

一开始本来想写线段树结果发现会 T,最后还是换成了队列模拟。

注意开 long long 的问题。有些地方虽然合法在 int 范围内,但不合法的情况会炸。

最新文章

  1. OPEN CASCADE编译视频
  2. Hibernate的延迟加载
  3. CSS 会被继承的属性
  4. IOS MenuController初步了解
  5. php部分--面向对象三大特性-封装(另加连续调用的一个例子)、继承(重写、重载的例子)、多态;
  6. iOS-xib(使用XIB实现嵌套自定义视图)
  7. POI HSSFColor 颜色索引对照表
  8. motan源码分析三:与spring框架的结合
  9. UVA10199- Tourist Guide(割点)
  10. Bootstrap学习之一起步
  11. javascript模块化开发编程
  12. Hibernate---O/R Mapping
  13. java装箱跟拆箱解析
  14. 查看某个ip地址接在交换机的哪个接口
  15. 在海航云中部署 keepalived
  16. selenium + robotframework的运行原理
  17. github删除某个库repository
  18. AUI-靠谱的移动前端框架
  19. 【校招面试 之 C/C++】第3题 为什么要内存对齐?以及内存对齐的方式
  20. 纸壳CMS可视化建站系统搭建多语言网站

热门文章

  1. 全局设置UITableView的属性|正确计算contentSize|MJRefresh mj_footer 能正常隐藏在底部,不因为数据过少展示在页面中部
  2. hdu4757 可持续字典树
  3. Flutter “孔雀开屏”的动画效果
  4. PHP绘图案例讲解验证码制作
  5. Python __str__(self)
  6. 阿里短信回持.net sdk的bug导致生产服务cpu 100%排查
  7. js解析MarkDown语法
  8. win服务器管理软件巧利用——如何让服务器管理事半功倍
  9. DM7的聚簇索引和非聚簇索引(cluster属性)
  10. ASP.NET实现一个在线音乐统计网站(歌手,音乐,角色……增删改查)