砍 树 砍树 砍树
题目链接:luogu P1873
题目
伐木工人米尔科需要砍倒 M M M米长的木材。这是一个对米尔科来说很容易的工作,因为他有一个漂亮的新伐木机,可以像野火一样砍倒森林。不过,米尔科只被允许砍倒单行树木。
米尔科的伐木机工作过程如下:米尔科设置一个高度参数 H H H(米),伐木机升起一个巨大的锯片到高度 H H H,并锯掉所有的树比 H H H高的部分(当然,树木不高于 H H H米的部分保持不变)。米尔科就行到树木被锯下的部分。
例如,如果一行树的高度分别为 20 20 20, 15 15 15, 10 10 10和 17 17 17,米尔科把锯片升到 15 15 15米的高度,切割后树木剩下的高度将是 15 15 15, 15 15 15, 10 10 10和 15 15 15,而米尔科将从第 1 1 1棵树得到 5 5 5米,从第 4 4 4棵树得到 2 2 2米,共得到 7 7 7米木材。
米尔科非常关注生态保护,所以他不会砍掉过多的木材。这正是他为什么尽可能高地设定伐木机锯片的原因。帮助米尔科找到伐木机锯片的最大的整数高度 H H H,使得他能得到木材至少为 M M M米。换句话说,如果再升高 1 1 1米,则他将得不到 M M M米木材。
输入
第
1
1
1行:
2
2
2个整数
N
N
N和
M
M
M,
N
N
N表示树木的数量,
M
M
M表示需要的木材总长度
第
2
2
2行:
N
N
N个整数表示每棵树的高度。所有木材长度之和大于
M
M
M,因此必有解。
输出
第 1 1 1行: 1 1 1个整数,表示砍树的最高高度。
样例输入
5 20
4 42 40 26 46
样例输出
36
数据范围
1
<
=
N
<
=
1000000
1<=N<=1000000
1<=N<=1000000
1
<
=
M
<
=
2000000000
1<=M<=2000000000
1<=M<=2000000000
每
棵
树
的
高
度
<
=
1000000000
每棵树的高度<=1000000000
每棵树的高度<=1000000000
思路
这道题我们用二分来做。
二分砍的高度,统计出能看出的木材。但是否大于
M
M
M,达到了就可以二分更高的,否则二分更低的。
代码
#include<cstdio>
#define ll long long
#define max(x,y) (x)>(y)?(x):(y)
#define min(x,y) (x)<(y)?(x):(y)
using namespace std;
ll n,m,a[1000001],l,r;
int main()
{
scanf("%lld%lld",&n,&m);//读入
for (ll i=1;i<=n;i++)
{
scanf("%lld",&a[i]);//读入
r=max(r,a[i]);//找到答案最大值
}
while (l<=r)//二分
{
ll mid=(l+r)>>1,sum=0;
for (ll i=1;i<=n;i++)
if (a[i]>mid)//看能不能砍到这棵树
sum+=a[i]-mid;//统计能看到的
if (sum<m) r=mid-1;//可以砍到的木量没有达到了M
else l=mid+1;//达到了
}
printf("%lld",l-1);//输出
return 0;
}