逆元

1  2   3

扩展欧几里得

void exgcd(ll a,ll b,ll &x,ll &y)//扩展欧几里得
{
    if(b==0) {x=1;y=0;return;}
    exgcd(b,a%b,y,x);
    y-=x*(a/b);
    return;
}

ll inv(ll a, ll n)//求a在模n下的逆元
{
    ll x,y;
    exgcd(a,n,x,y);
    x = (x%n+n)%n;
    return x;
}

把a/b变成a*x,x为b的逆元;

 

费马小定理

ll power(ll a, ll x) {
    ll ans = 1;
    while(x) {
        if(x&1) ans = (ans * a) %mod;
        a = (a * a) %mod;
        x >>= 1;
    }
    return ans;
} 

ll inv(ll a) {
    return power(a, mod - 2);
}

 

 

例题 :    hdu1576

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 #include <cmath>
 6 using namespace std;
 7 
 8 #define mem(a) memset(a,0,sizeof(a))
 9 #define ll long long
10 
11 void exgcd(ll a,ll b,ll &x,ll &y)//扩展欧几里得
12 {
13     if(b==0) {x=1;y=0;return;}
14     exgcd(b,a%b,y,x);
15     y-=x*(a/b);
16     return;
17 }
18 
19 ll inv(ll a, ll n)//求a在模n下的逆元
20 {
21     ll x,y;
22     exgcd(a,n,x,y);
23     x = (x%n+n)%n;
24     return x;
25 }
26 
27 int main()
28 {
29     int t;
30     ll a,b,n=9973;
31     scanf("%d",&t);
32     while(t--)
33     {
34         scanf("%lld%lld",&a,&b);
35         b = inv(b,n);
36         ll ans = (a*b)%n;
37         printf("%lld\n",ans);
38     }
39     return 0;
40 }
代码

 

posted on 2019-07-31 09:27  By_布衣  阅读(99)  评论(0编辑  收藏  举报

导航