A+B

A+B
Time Limit: 10000ms, Special Time Limit:25000ms, Memory Limit:65536KB
Total submit users: 19, Accepted users: 4
Problem 12899 : No special judgement
Problem description

There is a computer, which has two memory cells (let us denote these cells by the letters a and b). Each cell (variable) stores some integer at any time. The computer can execute only two instructions a+=b and b+=a. The first instruction increases the value of the variable a by the value stored in the variable b. The second one, respectively, increases the value of b by the value a. A program for this computer consists of a sequence (possible empty) of such instructions. The instructions are executed in the appropriate order. Your task is to determine whether the given value S can be obtained in some cell after executing some program.


Input

The input file contains three integers: the initial value of the variable a, the initial value of the variable b and the required value S (0 ≤ a, b, S ≤ 10^18).


Output

Output YES if the required value can be obtained as a result of some program execution, or NO otherwise.

Sample Input
1 2 3

3 4 5

3 4 17
Sample Output
YES

NO

YES
 
 
#include<iostream>//ax+by=c,求解x,y最小整数解,x,y,必互素。不过为毛。。。不晓得 
#include<cmath>
#define ll __int64
#define maxn 1000000000
using namespace std;
//举例 3x+4y=1 ax+by=1
//得到一组解x0=-1,y0=1 通解为x=-1+4k,y=1-3k 
//5,8,10这组数据不可以,因为只有a+=b,或 b+=a, 不能自己加自己。变了之后a,b,的值也变了
/* b=a+b; a=2*a+b; b=3*a+2*b; a=5*a+3*b; b=8*a+5*b; a=13*a+8*b; */ 

inline __int64 ggcd(__int64 a,__int64 b)//gcd模版 
{
    if(!b) return a;
    else
    return ggcd(b,a%b);
}


inline void gcd(ll a, ll b, ll &d, ll &x, ll &y)//扩展欧几里德的模版,留着 
{
    if(!b){d = a; x = 1; y = 0;}
    else{gcd(b,a%b,d,y,x);y -= x*(a/b);}
}

//(a/b)%mod=c 逆元为p,(p*b)%mod=1 
//(a/b)*(p*b)%mod=c*1%mod=c 
// (p*b)%mod=1 等价于 p*b-(p*b)/mod*mod=1其中要求p,b已知 等价于 ax+by=1
//其中x=p(x就是逆元),y=p/mod,a=b,b=b*mod 那么调用extend_gcd(b,b*mod,x,y)即可求(a/b)%mod的逆元等价于a*p%mod 
int main()
{
    __int64 a,b,x,y,c,mod,w,p,A,B;//ax+by=c
        while(scanf("%I64d%I64d%I64d",&a,&b,&c)!=EOF)
        {
        if((a == 1 && c > b)||(b == 1 && c > a)|| a == c || b == c)//又是特判 
        {
            printf("YES\n");
            continue;
        }
        if(a == 0 && b == 0)//特判 
        {
            printf("NO\n");
            continue;
        }
        if(a == 0)//特判 
        {
            if(c%b == 0) printf("YES\n");
            else printf("NO\n");
            continue;
        }
        if(b == 0)//特判 
        {
            if(c%a == 0) printf("YES\n");
            else printf("NO\n");
            continue;
        }
        bool flag=0; 
        if(c%ggcd(a,b)){cout<<"NO"<<endl;continue;}
        //扩展欧几里德求值方面 
        A = a/ggcd(a,b);
        B = b/ggcd(a,b);
        gcd(A,B,w,x,y);
        x = (c/ggcd(a,b)%B)*(x%B);//x,y,即为解 
        x %= B;//又%B 
        if(x<0) 
        x+=B;//x为最小整数 
        y=(c/ggcd(a,b)-x*A)/B;//由x求y 
        while(y>0)
        {
            if(ggcd(x,y)==1)
            {
              flag=1;
              break;
            }
            x+=B;
            y-=A;
        }
        cout<<x<<" "<<y<<endl; 
        if(flag==0)
        cout<<"NO"<<endl;
        else
        cout<<"YES"<<endl;
        }
    return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值