乘法逆元的应用(51nod 1013)

1.拓展欧几里得求逆元

  1. #include <bits/stdc++.h>  
  2. typedef long long ll;  
  3. using namespace std;  
  4. ll x,y;  
  5. ll eggcd(ll m,ll n)  
  6. {  
  7.     if(n==0)  
  8.     {  
  9.         x=1;  
  10.         y=0;  
  11.         return m;  
  12.     }  
  13.     int r=eggcd(n,m%n);  
  14.     int t=x;  
  15.     x=y;  
  16.     y=t-(m/n)*y;  
  17.     return r;  
  18. }  
  19. int main()  
  20. {  
  21.     ios::sync_with_stdio(false);  
  22.     ll n,m;  
  23.     while(cin>>m>>n)  
  24.     {  
  25.         eggcd(m,n);  
  26.         if(x<0)  
  27.         {  
  28.             x+=n;  
  29.         }  
  30.         cout<<x<<endl;  
  31.     }  
  32.     return 0;  
  33. }  

2.逆元应用 

在除法取余时,会出现精度问题导致结果出错

所以用逆元 可以用乘法代替除法取余

譬如

ans =(( (an * 3) - a0 ) / 2 ) % 1000000007;

和 ans =(( (an * 3) - a0 )  * (2 对 1000000007 求逆元) ) % 1000000007;

答案是相同的



51nod 1013 3的幂的和


可以用快速幂求出第N项

然后用等比求和

下面贴上自己的代码
#include <iostream>
#include <cmath>
using namespace std;
typedef long long ll;
ll N;
const ll mod=1000000007;
int quick(ll a,ll b)
{
    ll ans=1;
    while(b)
    {
        if(b&1)
            ans=(ans*a)%mod;
        a=(a*a)%mod;
        b>>=1;
    }
    return ans%mod;
}
int main()
{
    ios::sync_with_stdio(false);
    cin>>N;
    if(N==1)
    {
        cout<<1<<endl;
        return 0;
    }
    else
    {
        ll k=quick(3,N),sum;
        sum=(((k*3)%mod-3)*500000004)%mod;
        cout<<sum+1<<endl;
        return 0;
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值