关于定义请看资料维基百科提供:
一般在ACM竞赛中应用为求最大公约数:
long long gcd(long long x,long long y)
{
return y==0?x: gcd(y,x%y);
}
应用一、求逆元:
描述:对于整数a,b满足 a*b=1(mod)n
则称b为a的逆元。
1.先看“扩展欧几里得算法”
扩展欧几里得算法是欧几里德算法(又叫辗转相除法)的扩展。已知整数a、b,扩展欧几里得算法可以在求得a、b的最大公约数的同时,能找到整数x、y(其中一个很可能是负数),使它们满足贝祖等式。
代码:
void gcd(int a,int b,int &d,int &x,int &y)
{
if(!b) {d=a;x=1;y=0;}
else{ gcd(b,a%b,d,x,y); y-=x*(a/b);}
}
其中d=GCD(a,b);
//mod n时,求a的逆
long long inverse(long long a,long long n)
{
long long d,x,y;
gcd(a,n,d,x,y);
return d==1? (x+n)%n:-1;//若返回-1,即d!=1,a的逆元不存在;
}
怎么想呢?
由欧几里德算法的出:
ax+by=gcd(a,b)
a*a1=1(mod)n===> a*a1 = k*n+1;===>a*a1 - k*n =1
a和n的最大公约数为1,其中组合系数为,a1,-k(相当于上面的x,y);
2.欧拉定理(费马-欧拉定理):已知a和n为正整数,并且a和p互素,
则aφ(p) ≡ 1 mod p。那么a*aφ(p)-1 ≡ 1 mod p aφ(p)-1 就为a的逆元。
ans=pow_mod(a,phi(n)-1,n); 如果n是素数,则 φ(p) =p-1
欧拉phi函数:(容斥原理求解)
int euler_phi(int n)
{
int m =(int) sqrt(n+0.5);
int ans = n;
for(int i=2;i<=m;i++)
{
if(n%i==0){
ans=ans/i*(i-1);
while(n%i==0) n/i;
}
}
if(n>1) ans =ans /n*(n-1);
}
素数筛选法:
int phi[maxn];
void phi_table(int n)
{
memset(phi,0,sizeof(int));
phi[1]=1;
for(int i=2;i<=n;i++)
{
if(!phi[i])
{
for(int j=i;j<=n;j+=i)
if(!phi[j]) phi[j]=j;
phi[j]=phi[j]/i*(i-1);
}
}
}
快速取膜:
long long pow_mod(long long a,long long p,long long n)
{
long long ans=1,buff=a;
while(b)
{
if(p&1) ans=(ans*buff)%n;
buff=(buff*buff)%n;
b>>1;
}
return (ans)%n;
}