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

【题目链接】: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;
}



你可能感兴趣的:(数学,HDU,扩展欧几里得,逆元)