HDU 1576 A+B(逆元)

A/B
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 7660 Accepted Submission(s): 6097

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

Input
数据的第一行是一个T,表示有T组数据。
每组数据有两个数n(0 <= n < 9973)和B(1 <= B <= 10^9)。

Output
对应每组数据输出(A/B)%9973。

Sample Input
2
1000 53
87 123456789

Sample Output
7922
6060

#include <iostream>
#include <stdio.h>
#include <string.h>

using namespace std;

const int MOD  = 9973;
/****************/
/*第一种*/
//扩展欧几里得法
void ex_gcd(long long int a,long long int b,long long int &x,long long int &y,long long int &d){
    if(!b){
        d = a;
        x = 1;
        y = 0;
    }
    else{
        ex_gcd(b,a%b,y,x,d);
        y-=x*(a/b);
    }
}
long long int inv(long long int a,long long int p)
{
    //MOD已知
     long long int d,x,y;
     ex_gcd(a,p,x,y,d);
     //已知a,和MOD互质
     return (x%p+p)%p;
}

/**************/
/*第二种方法,费马定理,快速幂*/
long long int pow_mod(long long int a,long long int b, long long int p)
{
    long long int ret = 1;
    while(b){
        if(b&1) ret = (ret*a)%p;
        a = (a*a)%p;
        b/=2;
    }
    return ret;
}
long long int Fermat(long long int a,long long int p)//费马小定理求解a关于b的逆元
{
    return pow_mod(a,p-2,p);

}
/***********/
/*第三种,*/
long long int INV(long long t,long long p){
    return t == 1?1:(p-p/t)*INV(p%t,p)%p;
}
int main()
{
    int T;
    cin >> T;
    while(T--){
 //   cout << "Helong long into world!" << endl;
    long long int n,b;
    cin >> n >> b;

    long long IN = inv(b,MOD);

    long long I3 = INV(b%MOD,MOD);

     long long I = Fermat(b,MOD);
   // cout << ((n%MOD)*I)%MOD<< endl;
   // cout << ((n%MOD)*IN)%MOD << endl;
    cout << ((n%MOD)*I3)%MOD<< endl;
    }
    return 0;
}

第三种方法可以求解多个逆元,改为记忆化递归,用数组存储

猜你喜欢

转载自blog.csdn.net/hanyanwei123/article/details/80156823