【链接】 我是链接,点我呀:)
【题意】
【题解】
二分最后的最大抵御值mid。 然后对于每个蘑菇。 都能算出来它要浇水几次mid/a[i](上取整) 然后如果第i个蘑菇没浇水达到要求次数。 就在i和i+1之间来回走动(注意改变第i+1个蘑菇的状态) 直到满足每个蘑菇的浇水需求为止。 注意如果到了最后一个蘑菇所在的位置之后。 如果这个蘑菇已经不需要浇水了 那么就没有必要来到第n个位置。直接在n-1位置停下来就ok了【代码】
#include <bits/stdc++.h>
#define ll long long
#define rep1(i,a,b) for (int i = a;i <= b;i++)
#define rep2(i,a,b) for (int i = a;i >= b;i--)
using namespace std;
const int N = 1e5;
int n;
ll m;
ll a[N+10];
ll b[N+10];
bool ok(ll mid){
if (mid==0) return true;
for (int i = 1;i <= n;i++){
b[i] = mid/a[i];
if (mid%a[i]!=0) b[i]++;
}
ll cur = m;
for (int i = 1;i <= n;i++){
if (i==n && b[i]<=0) return true;
if (cur<=0) return false;
cur--;
if(b[i]>=1){
b[i]--;
cur-=(b[i]*2);
b[i+1]-=b[i];
if (cur<0) return false;
}
}
return true;
}
int main(){
// freopen("rush.txt","r",stdin);
int T;
scanf("%d",&T);
while (T--){
scanf("%d%lld",&n,&m);
for (int i = 1;i <= n;i++) scanf("%lld",&a[i]);
ll l = 0,r = 1e17,temp = -1;
while (l<=r){
ll mid = (l+r)>>1;
// printf("%lld
",mid);
if (ok(mid)){
temp = mid;
l = mid + 1;
}else{
r = mid - 1;
}
}
printf("%lld
",temp);
}
return 0;
}