Codeforces Round #299 (Div. 2)——C. Tavas and Karafs

快被二分搞死了。。。听一个大神说最好选择一种适合自己的写法然后搞懂它。

一开始用昨天那种写法,发现姿势不对,于是跑去又重新搞了一遍二分写法的区别。

题意:

现在告诉你每个点i的高度的求法是si=A+B*(i-1);然后有n次询问,对于每次询问我们给出l,t,m,分别代表起点l,然后是最多可以吃的次数t,每次最多可以吃掉几个食物m。

每次吃一个食物只能把每个食物的高度减少1。然后问你在满足上述的条件的情况下,我们最多可以吃到终点在哪儿的食物,也就是找到r。注意,我们必须把所有的食物都吃到高度为0才可以!

思路:

我们可以用二分来求终点r,然后再进行判断。

判断:

1)首先是最大的高度要小于天数,要不然最大的那个高度不可能被减少完。

2)因为总共可以进行减少m*t次,所以所有序列的和要小于等于m*t才可以。

还有注意一点就是要用__int64,要不然会错。

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<map>
#include<vector>
using namespace std;
#define maxn 1000010
typedef __int64 ll;
ll A,B,n;
ll l,t,m;
bool is_ok(ll mid){
    ll hmax=A+B*(mid-1);
    if(hmax>t) return false;
    ll sum=0;
    ll a1=A+B*(l-1);
    ll a2=A+B*(mid-1);
    sum=(a1+a2)*(mid-l+1)/2;
    if(sum>m*t) return false;
    return true;
}
ll bin(ll x,ll y){
    ll mid;
    ll ans=-1;
    while(x<y){
        mid=x+(y-x)/2;
        if(is_ok(mid)){
        	x=mid+1;
        	ans=max(ans,mid);	//二分的时候可以用一个变量来保存结果! 
		}
        else y=mid;
    }
    return ans;
}
int main(){
    scanf("%I64d%I64d%I64d",&A,&B,&n);
    while(n--){
        scanf("%I64d%I64d%I64d",&l,&t,&m);
        ll ans=bin(l,maxn+1);
        if(ans<l||ans>1000000) printf("-1\n");
        else printf("%I64d\n",ans);
    }
}
/*
2 1 4
1 5 3
3 3 10
7 10 2
6 4 8
*/


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值