(a+b)%p = ( a%p+b%p) % p
加法,减法,乘法 可以用,除法不可,转化成乘法,用逆元
板子1. 求得x,y使得 ax+by=gcd(a,b),返回ans为最大公因数
//求得x,y使得 ax+by=gcd(a,b),返回ans为最大公因数
例如 exgcd(5,7,x,y),运行后x=3,y=-2,ans=1;
ll exgcd(ll a,ll b,ll &x,ll &y){
if(!b){
x=1;y=0;return a;
}else {
ll ans = exgcd(b,a%b,x,y);
ll temp=x;
x=y;
y=temp-a/b*y;
return ans;
}
}
板子2.求逆元 a关于m的逆元x,即a*x mod m==1
//ax = 1(mod n)
long long mod_reverse(long long a,long long n)
{
long long x,y;
long long d=extend_gcd(a,n,x,y);
if(d==1) return (x%n+n)%n;
else return -1;
}
板子2.求逆元 费马小定理
a的m-2次就是a关于m的逆元
ll quick_pow(ll a, ll b){
if(b < 0) return 0;
ll ret = 1;
a %= MOD;
while(b){
if( b & 1) ret = (ret * a) % MOD;
b >>= 1;
a = (a * a) % MOD;
}
return ret;
}
ll inv(ll a,ll m){
return quick_pow(a,m - 2);
}
例题
zoj3609
求最小的x满足 ax≡1 (mod m)
a=3,m=11,则x=4;
const int MAXN=2550;
const int MOD=9973;
//求得x,y使得 ax+by=gcd(a,b)
ll exgcd(ll a,ll b,ll &x,ll &y){
if(!b){
x=1;y=0;return a;
}else {
ll ans = exgcd(b,a%b,x,y);
ll temp=x;
x=y;
y=temp-a/b*y;
return ans;
}
}
//求逆元 ax = 1(mod m)
ll cal(ll a,ll m){
ll x,y;
ll gcd=exgcd(a,m,x,y);
if(gcd==1)return (x%m+m)%m;
else return -1;
}
int main(){
SIS;
int c;cin>>c;
while(c--){
ll a,b;
cin>>a>>b;
ll ans=cal(a,b);
if(ans==-1)cout<<"Not Exist"<<endl;
else if(ans==0)cout<<"1"<<endl;
else cout<<ans<<endl;
}
return 0;
}
hdu1576
要求(A/B)%9973,但由于A很大,我们只给出n(n=A%9973)(我们给定的A必能被B整除,且gcd(B,9973) = 1)。
const int MAXN=2550;
const int MOD=9973;
//求得x,y使得 ax+by=gcd(a,b)
ll exgcd(ll a,ll b,ll &x,ll &y){
if(!b){
x=1;y=0;return a;
}else {
ll ans = exgcd(b,a%b,x,y);
ll temp=x;
x=y;
y=temp-a/b*y;
return ans;
}
}
//求逆元 ax = 1(mod m)
ll cal(ll a,ll m){
ll x,y;
ll gcd=exgcd(a,m,x,y);
if(gcd==1)return (x%m+m)%m;
else return -1;
}
int main(){
SIS;
int c;cin>>c;
while(c--){
ll a,b;
cin>>a>>b;
ll ans=cal(b,MOD);
ans%=MOD;
cout<<a*ans%MOD<<endl;
}
return 0;
}
另外还有两种求逆元的方式
//求1,2,...,N关于 M 的逆元(M为质数)
int inv[maxn];
inv[1] = 1;
for(int i = 2; i < 10000; i++)
inv[i] = inv[mod % i] * (mod - mod / i) % mod;
//求阶乘的逆元
inv[maxn]=mod_pow(fac[maxn],mod-2); // fac[] 是阶乘数组
for(ll i=maxn-1;i>=0;i--)
inv[i]=(inv[i+1]*(i+1))%mod;