HDU1576 A/B 求乘法逆元模版

来源:互联网 发布:java b2b2c 开源 编辑:程序博客网 时间:2024/04/20 05:41

HDU1576A/B

ABmod9973
已知gcd(B,9973)=1,所以AB(mod9973)=AB1(mod9973),重在求乘法逆元:

由于B9973=1,利用Fermat小定理最简单,逆元即为Bmod2
AC代码:

/*************************************************************** By: Xingxing* Date: 2016-09-26* Address: http://blog.csdn.net/legend_pawn?viewmode=contents**************************************************************/#include <iostream>#include <cstdio>typedef long long ll;const int mod=9973;using namespace std;ll quickpow(ll a,ll b){    int res=1;    while(b>0){        if(b&1)            res=res*a%mod;        b=b>>1;        a=(a%mod)*(a%mod)%mod;    }    return res;}int main(){    //freopen("input.txt","r",stdin);    int T;    cin>>T;    while(T--){        int n,b;        scanf("%d%d",&n,&b);        ll ans;        ans=n*quickpow(b,9971)%mod;        cout<<ans<<endl;    }    return 0;}

另一种方法是扩展欧几里得求乘法逆元,即求解不定方程b1b+9973y=1

AC代码:

/*************************************************************** By: Xingxing* Date: 2016-09-26* Address: http://blog.csdn.net/legend_pawn?viewmode=contents**************************************************************/#include <iostream>#include <cstdio>typedef long long ll;const int MOD=9973;using namespace std;ll extend_gcd(ll a,ll b,ll &x,ll &y){    if(a==0 &&b==0)        return -1;    if(b==0){        x=1;y=0;return a;    }    ll d=extend_gcd(b,a%b,y,x);    y-=a/b*x;    return d;}ll mod_reserve(ll a){    ll x,y;    ll d=extend_gcd(a,MOD,x,y);    if(d==1)        return (x+MOD)%MOD;    else        return -1;}int main(){    //freopen("input.txt","r",stdin);    int T;    scanf("%d",&T);    while(T--){        int n,b;        scanf("%d%d",&n,&b);        ll ans;        ans=(n*(mod_reserve(b)%MOD))%MOD;        cout<<ans<<endl;    }    return 0;}

最后一种:
要求 求1,2,,p1modp 的逆元,然后就看到了一个 O(n) 的做法
这个做法实际上是这样的,首先111  (mod p)
然后我们设:p=ki+r,r<i,1<i<p
再将这个算式放到modp的意义下得到:

kr+i0  (mod p)

两边同时乘上i1,r1
kr1+i10     (mod p)i1kr1     (mod p)i1pip (mod i)     (mod p)

代码:

A[i] = -(p / i) * A[p % i];
0 0
原创粉丝点击