一、欧拉函数
1.欧拉函数的定义
2.求一个数的欧拉函数
int get_euler(int a){
int res=a;
for(int i=2;i<=a/i;i++){
if(a%i==0){//试除法找质因子
res=res/i*(i-1);
while(a%i==0) a/=i;
}
}
if(a>1) res=res/a*(a-1);//大于a/i的质因子
return res;
}
3.求小于n的欧拉函数之和
int sum_eulers(int n){
phi[1]=1;//数组phi存欧拉函数值
for(int i=2;i<=n;i++){//求每个数的欧拉函数
if(!st[i]){
primes[cnt++]=i;
phi[i]=i-1;
}
for(int j=0;primes[j]<=n/i;j++){//同线性筛数法求质因子
st[primes[j]*i]=true;
if(i%primes[j]==0){//primes[j]不是primes[j]*i的质因子
//质因子相同,N部分乘primes[j]
phi[primes[j]*i]=phi[i]*primes[j];
break;
}
//质因子部分除以primes[j],N部分乘primes[j],二者抵消了
phi[primes[j]*i]=phi[i]*(primes[j]-1);
}
}
long long int res=0;
for(int i=1;i<=n;i++) res+=phi[i];//求和
return res;
}
二、欧拉定理与费马小定理
1.欧拉定理
若a与n互质,则 (mod n)。例:当a=5,n=6时,由于6的欧拉函数为2,则25与1对于模6相等。
2.费马小定理
若p是一个质数,a为不是p的倍数的整数,则 (mod p)。
三、快速幂
主要思想:在O(logk)内求出mod p。先预处理计算出logk个值:mod k,mod k... mod k,可以这些值的乘积表示。由底数相同的数相乘即把指数相加,可以把k拆解成到的和,即相当于用二进制表示k,当k的二进制表示在第i位为1时,就将答案乘以mod p。
例题:给出三个数a,k,p,求mod p。
int qmi(int a,int k,int p){
int res=1;
while(k){
if(k&1) res=res*a%p;//k的最低位为1,乘以第i个预处理数
k>>=1;//k右移一位
a=a*a%p;//由第i个预处理数求第i+1个预处理数
}
return res;
}
应用:求一个数的乘法逆元。由乘法逆元的定义以及费马小定理可以得,求一个数a的乘法逆元即为求mod p,代入快速幂公式。