1. 程式人生 > >hdu 1576 A/B(乘法逆元)

hdu 1576 A/B(乘法逆元)

題目連結:http://acm.hdu.edu.cn/showproblem.php?pid=1576

題目思路:  求(A/B)%9973,等於是求B的逆元乘上n.求數的逆元可以用歐幾里得演算法求逆元。又因為9973是素數滿足費馬小定理

a^{p-1}\equiv 1 mod p,即a*a^{p-2}\equiv 1modp,所以b的逆元= a^{p-2},使用快速冪即可求得。

歐幾里得程式碼:

#include <cstdio>

using namespace std;
typedef long long ll;
const ll MOD=9973;
ll gcdExtended(ll a, ll b, ll *x, ll *y){
 
    if (a == 0){
        *x = 0;
        *y = 1;
        return b;
    }
    ll x1, y1;
    ll gcd = gcdExtended(b%a, a, &x1, &y1);
 
    *x = y1 - (b/a) * x1;
    *y = x1;
 
    return gcd;
}
int main(){
	int T;scanf("%d",&T);
	ll x,y,b,n;
	while(T--){
		scanf("%lld%lld",&n,&b);
		gcdExtended(b,MOD,&x,&y);
		x=(x+MOD)%MOD;
		printf("%lld\n",x*n%MOD);
	}
	return 0;
}

費馬小定理程式碼:

#include <cstdio>

using namespace std;
typedef long long ll;
const ll MOD = 9973;

ll power(ll a,ll n){
	ll res=1;
	while(n){
		if(n&1) res=(res*a)%MOD;
		a=(a*a)%MOD;
		n>>=1;
	}
	return res;
}



int main(){
	ll n,b;
	int T;scanf("%d",&T);
	while(T--){
		scanf("%lld%lld",&n,&b);
		//b的逆元
		ll invb=power(b,MOD-2)%MOD;
		ll ans=(n%MOD*invb)%MOD;
		printf("%lld\n",ans);
	}
		
	return 0;
}