Educational Codeforces Round 61 (Rated for Div. 2)D(二分,模拟,思维)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int n,k;
ll a[200007],b[200007],s[200007];
ll ans;
int check(ll val){
 memset(s,0,sizeof(s));
 int num=k;
 for(int i=1;i<=n;i++){
  if(!b[i])
   continue;
  s[min(a[i]/b[i]+1,1ll*(k+1))]++;//计算这台电脑何时需要充电
  ll sum=a[i];
  while(sum<1ll*k*b[i]){//如果这台电脑撑不到比赛结束
   if(!num)//充电器没有档期
    break;
   sum+=val;//充一次电
   s[min(sum/b[i]+1,1ll*(k+1))]++;//计算何时需要充电
   num--;//充电器档期-1
  }
 }
 for(int i=1;i<=k;i++){
  s[i]+=s[i-1];//统计此时已经充了几次电
  if(s[i]>i)//充电器做不到啊
   return 0;
 }
 return 1;
}
int main(){
 scanf("%d%d",&n,&k);
 k--;
 for(int i=1;i<=n;i++)
  scanf("%lld",&a[i]);
 for(int i=1;i<=n;i++)
  scanf("%lld",&b[i]);
 ll l=0,r=2e12;//r为极限答案,k_max*b[i]_max,这样充一次足以满足耗电量最大的电脑度过最长的时间,和初始电量并无关联
 while(l<=r){//二分答案
  ll mid=(l+r)>>1;
  if(check(mid)){
   ans=mid;
   r=mid-1;
  }
  else
   l=mid+1;
 }
 if(!ans){
        if(check(0))
            printf("0");
        else
            printf("-1");
 }
 else
  printf("%lld",ans);
}

猜你喜欢

转载自www.cnblogs.com/ldudxy/p/10486504.html