rng_10s 【数论】(扩展欧几里得)

题目描述

Ringo Mart, a convenience store, sells apple juice.
On the opening day of Ringo Mart, there were A cans of juice in stock in the morning. Snuke buys B cans of juice here every day in the daytime. Then, the manager checks the number of cans of juice remaining in stock every night. If there are C or less cans, D new cans will be added to the stock by the next morning.
Determine if Snuke can buy juice indefinitely, that is, there is always B or more cans of juice in stock when he attempts to buy them. Nobody besides Snuke buy juice at this store.
Note that each test case in this problem consists of T queries.

Constraints
1≤T≤300
1≤A,B,C,D≤1018
All values in input are integers.

 

输入

Input is given from Standard Input in the following format:
T
A1 B1 C1 D1
A2 B2 C2 D2
:
AT BT CT DT
In the i-th query, A=Ai,B=Bi,C=Ci,D=Di.

 

输出

Print T lines. The i-th line should contain Yes if Snuke can buy apple juice indefinitely in the i-th query; No otherwise.

 

样例输入

14
9 7 5 9
9 7 6 9
14 10 7 12
14 10 8 12
14 10 9 12
14 10 7 11
14 10 8 11
14 10 9 11
9 10 5 10
10 10 5 10
11 10 5 10
16 10 5 10
1000000000000000000 17 14 999999999999999985
1000000000000000000 17 15 999999999999999985

样例输出

No
Yes
No
Yes
Yes
No
No
Yes
No
Yes
Yes
No
No
Yes

 

提示

In the first query, the number of cans of juice in stock changes as follows: (D represents daytime and N represents night.)

***
In the second query, the number of cans of juice in stock changes as follows:

and so on, thus Snuke can buy juice indefinitely.

 

分析:

参考:https://blog.csdn.net/qq_34454069/article/details/81055250

扩展欧几里得是用来在已知a, b求解一组xy,使它们满足贝祖等式: ax+by = gcd(a, b) =d(解一定存在,根据数论中的相关定理)

ax+by凑出的一定是d的倍数

 

特殊的:a<b||d<b 输出No

一般情况下:1.a>=b&&d>=b

  若c<a-bx+dy<b 有解输出No   (即可以消耗到大于c 但是小于b 那么下一天则不符合)

  即a-b<bx-dy<a-c有解

  又因为bx-dy一定等于gcd(b,d)的倍数

  所以就是求gcd(b,d)的倍数有没有在(a-b,a-c)的

    若有则No

    否则Yes

代码:

 

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;

ll gcd(ll a,ll b){return a%b==0?b:gcd(b,a%b);}

int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        ll a,b,c,d;
        scanf("%lld%lld%lld%lld",&a,&b,&c,&d);
        if(a<b||d<b)
        {
            printf("No\n");
            continue;
        }
        if(c+1>=b)
        {
            printf("Yes\n");
            continue;
        }
        ll tmp = gcd(b,d);
        ll one = 1;
        if((a-c-one)/tmp-(a-b)/tmp>0)
            printf("No\n");
        else
            printf("Yes\n");
    }
}

 

 

 

posted @ 2019-02-14 19:55  zangzang  阅读(237)  评论(0编辑  收藏  举报