[模板] 乘法逆元及其应用 (51nod 1013 3的幂的和)
1.拓展欧几里得求逆元
#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
ll x,y;
ll eggcd(ll m,ll n)
{
if(n==0)
{
x=1;
y=0;
return m;
}
int r=eggcd(n,m%n);
int t=x;
x=y;
y=t-(m/n)*y;
return r;
}
int main()
{
ios::sync_with_stdio(false);
ll n,m;
while(cin>>m>>n)
{
eggcd(m,n);
if(x<0)
{
x+=n;
}
cout<<x<<endl;
}
return 0;
}
2.逆元应用
在除法取余时,会出现精度问题导致结果出错
所以用逆元 可以用乘法代替除法取余
譬如
ans =(( (an * 3) - a0 ) / 2 ) % 1000000007;
和 ans =(( (an * 3) - a0 ) * (2 对 1000000007 求逆元) ) % 1000000007;
答案是相同的
51nod 1013 3的幂的和
可以用快速幂求出第N项
然后用等比求和
#include <iostream>
using namespace std;
typedef long long ull;
const int MOD = 1e9 + 7;
ull qpow ( ull x, ull n)
{
ull ans = 1;
while(n)
{
if(n & 1)
ans = (ans * x) % MOD ;
x = (x * x) % MOD;
n = n >> 1;
}
return ans;
}
int main()
{
ull n;
while(cin>>n)
{
ull an = qpow(3, n), a0 = 1;
ull ans;
ans =(( (an * 3) - a0 )* 500000004 ) % MOD;
cout<<ans<<endl;
}
return 0;
}