HDU 1576 A/B (逆元求扩展欧几里得)

来源:互联网 发布:笔记本电脑安装centos 编辑:程序博客网 时间:2024/05/16 12:18

【题目链接】:click here~~

【题目大意】:

要求(A/B)%9973,但由于A很大,我们只给出n(n=A%9973)(我们给定的A必能被B整除,且gcd(B,9973) = 1)。

【思路】,此题有多种方法,

法一:逆元解决就可以了。

代码:

/*  * Problem: HDU No.1576 * Running time: 0MS  * Complier: C++  * Author: javaherongwei * Create Time: 20:51 2015/9/2 星期三*/  #include <bits/stdc++.h>using namespace std;typedef long long LL;LL a,b;LL mod=9973;LL poww(LL a,LL b){    LL res=a,ans=1;    while(b)    {        if(b&1) ans=ans*res%mod;        res=res*res%mod;        b>>=1;    }    return ans;}LL niyuan(LL a){    return poww(a,mod-2);}int main(){    int t;scanf("%d",&t);    while(t--)    {        scanf("%lld %lld",&a,&b);        printf("%lld\n",a*niyuan(b)%mod);    } return 0;}

法二:扩展欧几里得:

【思路】:

设(A/B)%9973 = K, 则A/B = k + 9973 *x , 因此A = kB + 9973 *x*B,
又A%9973 = n, 所以kB%9973 = n,  故kB = n + 9973*y
故(k/n)B +(-y/n)*9973 = gcd(B,9973) = 1
扩展欧几里得 求出k/n

代码:

/** Problem: HDU No.1576* Running time: 15MS* Complier: C++* Author: javaherongwei* Create Time: 21:07 2015/9/2 星期三*/#include <bits/stdc++.h>using namespace std;typedef long long LL;LL a,b,x,y;LL mod=9973;void ext_gcd(LL &a,LL &b,LL n,LL m) // Extended Euclidean Algorithm{    if(m==0)    {        a=1;        b=0;        return ;    }    ext_gcd(a,b,m,n%m);    LL d=a;    a=b;    b=d-n/m*b;}int main(){    int t;scanf("%d",&t);    while(t--)    {        scanf("%lld %lld",&a,&b);        ext_gcd(x,y,b,mod);        x*=a;        x=(x%mod+mod)%mod;        printf("%lld\n",x);    } return 0;}



0 0