CodeForces_1461E Water Level(数论 + 贪心)

Water Level

time limit per test:1 seconds
memory limit per test:256 megabytes
Problem Description

In recent years John has very successfully settled at his new job at the office. But John doesn’t like to idly sit around while his code is compiling, so he immediately found himself an interesting distraction. The point of his distraction was to maintain a water level in the water cooler used by other zebras.

Originally the cooler contained exactly k k k liters of water. John decided that the amount of water must always be at least l l l liters of water but no more than r r r liters. John will stay at the office for exactly t t t days. He knows that each day exactly x x x liters of water will be used by his colleagues. At the beginning of each day he can add exactly y y y liters of water to the cooler, but at any point in time the amount of water in the cooler must be in the range [ l , r ] [l,r] [l,r].

Now John wants to find out whether he will be able to maintain the water level at the necessary level for t t t days. Help him answer this question!

Input

The first line of the input contains six integers k k k, l l l, r r r, t t t, x x x and y y y ( 1 ≤ l ≤ k ≤ r ≤ 1 0 18 1≤l≤k≤r≤10^{18} 1lkr1018; 1 ≤ t ≤ 1 0 18 1≤t≤10^{18} 1t1018; 1 ≤ x ≤ 1 0 6 1≤x≤10^6 1x106; 1 ≤ y ≤ 1 0 18 1≤y≤10^{18} 1y1018) — initial water level, the required range, the number of days, daily water usage and the exact amount of water that can be added, respectively.

Output

Print “Yes” if John can maintain the water level for t t t days and “No” otherwise.

Sample Input

8 1 10 2 6 4

Sample Output

No

题意

初始在饮水机中有 k k k升水,每天需要消耗 x x x升水,每天的一开始,John可以选择往饮水机中加 y y y升水(可以不加)。问 t t t天内是否能保证每时每刻饮水机内的水大于等于 l l l升,小于等于 r r r升。即 k ′ ∈ [ l , r ] k'\in[l,r] k[l,r]

思路

因为饮水机中的水都是要求在 [ l , r ] [l,r] [l,r]内,可以从 k − = l , r − = l k-=l,r-=l k=l,r=l,这样就能忽略 l l l的影响(从k升水中扣除l升水,该部分不可用)。
除了x,所有的数据范围都在1e18,所以可以考虑从x入手,分类讨论:

x > y x > y x>y,显然水位每天都会下降。此时考虑水能够多少天使用,常规状态下每天减少 ( x − y ) (x-y) (xy)升水,注意第一天能否加水,和第一天的水是否够用。

x ≤ y x\le y xy, 让饮水机中的水尽量少,如果够一天的使用,则不加水,如果不够一天的使用则加水。设k为饮水机中的剩余水量。当 k < x k<x k<x时,则必须加水:
k + y > r k+y>r k+y>r,不能加水,无解。
k + y ≤ r k+y\le r k+yr,能加水,则 k + = y k+=y k+=y,计算当前水能用几天,并且 k % = x k\%=x k%=x,若k在之前中的计算中出现过,则说明这些操作形成了循环,能保证水量一直在 [ 0 , r ] [0,r] [0,r]间,则有解。
t ≤ 0 t\le 0 t0,退出循环,则有解。

#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<map>
#include<vector>
#include<queue>
#include<iterator>
#include<unordered_map>
#define dbg(x) cout<<#x<<" = "<<x<<endl;
#define INF 0x3f3f3f3f
#define LLINF 0x3f3f3f3f3f3f3f3f
#define eps 1e-6
  
using namespace std;
typedef long long LL;
typedef pair<int, int> P;
const int maxn = 100100;
const int mod = 998244353;
unordered_map<LL,int> mp;
bool solve(LL k, LL r, LL x, LL y, LL t);

int main()
{
    LL k, l, r, t, x, y, a, b, c;
    scanf("%I64d %I64d %I64d %I64d %I64d %I64d", &k, &l, &r, &t, &x, &y);
    if(solve(k-l, r-l, x, y, t))puts("Yes");
    else puts("No");
    return 0;
}

bool solve(LL k, LL r, LL x, LL y, LL t)
{
    if(x>y){
        LL tmp;
        //若不能加水且不够一天的用水量
        if(k+y>r && k<x)tmp = 0;
        //若第一天不能加水,求则第一天用去x升,以后每天下降x-y升
        else if(k+y>r)tmp = 1+(k-x)/(x-y);
        //第一天能加水,则每天下降x-y升
        else tmp = k/(x-y);
        return tmp >= t;
    }else{
    	//计算处理水量能用的天数
        LL c = k/x;
        k -= c*x, t -= c;
        mp[k] = 1;
        while(t>0){
        	//当前情况不能加水,无解
            if(k+y > r)return false;
            //加水,并计算能用的天数
            t -= (k+y)/x;
            k = (k+y)%x;
            //形成循环,有解
            if(mp.count(k))return true;
            mp[k] = 1;
        }
    }
    return true;
}
  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值