【模板】有理数取余(exgcd)

【模板】有理数取余

题目描述

给出一个有理数 c = a b c=\frac{a}{b} c=ba,求 c   m o d   19260817 c \bmod 19260817 cmod19260817 的值。

这个值被定义为 b x ≡ a ( m o d 19260817 ) bx\equiv a\pmod{19260817} bxa(mod19260817) 的解。

输入格式

一共两行。

第一行,一个整数 a a a
第二行,一个整数 b b b

输出格式

一个整数,代表求余后的结果。如果无解,输出 Angry!

样例 #1

样例输入 #1

233
666

样例输出 #1

18595654

提示

对于所有数据,保证 0 ≤ a ≤ 1 0 10001 0\leq a \leq 10^{10001} 0a1010001 1 ≤ b ≤ 1 0 10001 1 \leq b \leq 10^{10001} 1b1010001,且 a , b a, b a,b 不同时是 19260817 19260817 19260817 的倍数。

思路

  • 首先,这个首先读入就是个麻烦事情,我们可以在读入的时候先求模,肯定不会对结果造成影响。
  • 其次,这道题要求 b x ≡ a ( m o d 19260817 ) bx\equiv a\pmod{19260817} bxa(mod19260817),这个我们可以转化成 b x + 19260817 y = a bx+19260817y=a bx+19260817y=a其中 g c d ( b , 19260817 ) = 1 gcd(b,19260817)=1 gcd(b,19260817)=1,如果不等于,则无解。
  • 最后,剩下的都是扩展欧几里得的内容了(说实话,因为19260817是素数,这道题还可以用费马定理(求乘法逆元的))。

代码

//可以在读入的时候%mod
#include<iostream>

using namespace std;

const int mod = 19260817;

typedef long long LL;

LL a,b;

LL getint(){
    string aa;
    cin>>aa;
    LL ans=0;
    for(int i=0;i<aa.size();i++){
        LL t=aa[i]-'0';
        ans=(ans*10+t)%mod;
    }
    return ans;
    
}

int exgcd(int a,int b,LL &x,LL &y){
    if(!b){
        x=1,y=0;
        return a;
    }
    
    int d=exgcd(b,a%b,y,x);
    y-=a/b*x;
    return d;
}

int main(){
    a=getint();
    b=getint();
    LL x,y;
    int d=exgcd(b,mod,x,y);
    //bx-mody=a
    
    if(a%d){
        puts("Angry!");
        return 0;
    }
    x*=a/d;
    int t=mod/d;
    cout<<(x%t+t)%t;
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

green qwq

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值