</pre><pre name="code" class="html">#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
const int maxn=1009;
//欧几里德算法又称辗转相除法,用于计算两个整数a,b的最大公约数。
//基本算法:设a=qb+r,其中a,b,q,r都是整数,
//则gcd(a,b)=gcd(b,r),即gcd(a,b)=gcd(b,a%b)。
//递归
int gcd(int a,int b)
{
return b ? gcd(b,a%b) : a;
}
//非递归
int Gcd(int a, int b)
{
// while(b!=0)
// {
// int r = b;
// b = a % b;
// a = r;
// }
while(b!=0)
{
int r=b;
b=a%b;
a=r;
}
return a;
}
//扩展欧几里德
//基本算法:对于不完全为 0 的非负整数 a,b,gcd(a,b)
//表示 a,b 的最大公约数,
//必然存在整数对 x,y ,使得 gcd(a,b)=ax+by
int exgcd(int a,int b,int &x,int &y)
{
if(b==0)
{
x=1;
y=0;
return a;
}
int r=exgcd(b,a%b,x,y);
int t=x;
x=y;
y=t-a/b*y;
return r;
}
//非递归
int exgcd(int m,int n,int &x,int &y)
{
int x1,y1,x0,y0;
x0=1; y0=0;
x1=0; y1=1;
x=0; y=1;
int r=m%n;
int q=(m-r)/n;
while(r)
{
x=x0-q*x1; y=y0-q*y1;
x0=x1; y0=y1;
x1=x; y1=y;
m=n; n=r; r=m%n;
q=(m-r)/n;
}
return n;
}
//扩展欧几里德算法的应用主要有以下三方面:
//
//(1)求解不定方程;
//
//(2)求解模线性方程(线性同余方程);
//
//(3)求解模的逆元;
//(1)求解不定方程;
bool linear_equation(int a,int b,int c,int &x,int &y)
{
int d=exgcd(a,b,x,y);
if(c%d)
return false;
int k=c/d;
x*=k; y*=k; //求得的只是其中一组解
return true;
}
//(2)求解模线性方程(线性同余方程);
bool modular_linear_equation(int a,int b,int n)
{
int x,y,x0,i;
int d=exgcd(a,n,x,y);
if(b%d)
return false;
x0=x*(b/d)%n; //特解
for(i=1;i<d;i++)
printf("%d\n",(x0+i*(n/d))%n);
return true;
}
//
//(3)用欧几里德算法求模的逆元:
//
//同余方程ax≡b (mod n),如果 gcd(a,n)== 1,则方程只有唯一解。
//
//在这种情况下,如果 b== 1,同余方程就是 ax=1 (mod n ),gcd(a,n)= 1。
//
//这时称求出的 x 为 a 的对模 n 乘法的逆元。
//
//对于同余方程 ax= 1(mod n ), gcd(a,n)= 1 的求解就是求解方程
//
//ax+ ny= 1,x, y 为整数。这个可用扩展欧几里德算法求出,
//原同余方程的唯一解就是用扩展欧几里德算法得出的 x 。
//模算术
int mul_mod(int a,int b,int n)
{
return a*b%n;
}
//a的p次方mod n,要求0<=a<n
int pow_mod(int a,int p,int n)
{
if(p==0)
return 1;
int ans=pow_mod(a,p/2,n);
ans=ans*ans%n;
if(p%2==1)
ans=ans*a%n;
return ans;
}
int main()
{
int a,b,n;
while(scanf("%d%d%d",&a,&b,&n)!=EOF)
{
int ans=pow_mod(a,b,n);
printf("%d\n",ans);
}
return 0;
}
欧几里德和扩展欧几里德
最新推荐文章于 2021-10-20 21:42:25 发布