newcoder猴子吃香蕉

题目描述

有n只猴子,第i只猴子每过xi小时会连续吃香蕉yi小时。猴子从第二次开始每次休息结束后这只猴子连续吃香蕉的时间会增加zi小时。

给定 n只猴子,每一只的 xi, yi, zi,以及时间 t,求在前 t小时中,所有猴子共吃了多少小时。
 对于一只猴子来说是这样的:
从第1小时开始: 
休息x i小时( 1 -> x i ) 
吃y i小时( x i + 1 -> x i + y )
休息x i小时
吃y i+z i小时
休息x i小时
吃y i+z i+z i小时
....
假设一个猴子吃了K阶段,K个阶段就是(x+y) + (x+y+z) + (x+y+z*2)  + (x+y+z*3)....
所以二分k的上限.然后再处理一下剩下的时间,注意z的值为0的情况,还有二分的上限不能过大.
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
typedef long long ll;
const int maxn = 1e5+10;
int n;
ll t;
ll x[maxn],y[maxn],z[maxn];
inline bool check(ll mid,int k)
{
    //printf("%lld %lld\n",mid,mid*(x[k]+y[k]) + mid*(mid-1)/2*z[k]);
    return mid*(x[k]+y[k]) + mid*(mid-1)/2*z[k]<=t;
}
int main()
{
    scanf("%d%lld",&n,&t);
    for(ll i=0;i<n;i++)
    {
        scanf("%lld%lld%lld",&x[i],&y[i],&z[i]);
    }
    ll sum = 0;
    for(ll i=0;i<n;i++)
    {
        if(z[i]==0&&y[i]!=0)
        {
            sum += t/(x[i]+y[i])*y[i];
            if(t%(x[i]+y[i])-x[i]>0)
            sum += t%(x[i]+y[i])-x[i];
            continue;
        }
        ll l = 0,r = 1e5,mid,ans;
        while(l<=r)
        {
            mid = (l+r)/2;
            int flag = check(mid,i);
            if(flag) l = mid+1,ans = mid;
            else r = mid-1;
        }
        sum += ans*y[i] + ans*(ans-1)/2*z[i];
        ll tmp = t-ans*(x[i]+y[i]) - ans*(ans-1)/2*z[i];
        tmp -= x[i];
        if(tmp>0&&y[i]&&z[i])
        {
            sum += tmp;
        }
        else if(tmp>0&&!y[i]&&z[i])
        {
            sum += tmp;
        }
    }
    printf("%lld\n",sum);
    return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值