目录
欧拉函数
欧拉函数φ(n)表示小于等于n的数中与n互质的正整数的个数
换句话说,
欧拉函数为积性函数,即有φ(p*q) = φ(p) * φ(q) 当且仅当p,q互质(gcd(p,q) = 1)
性质(p代表素数):
求解单个欧拉函数:
根据上述性质可以在分解n的质因数的时候计算
复杂度为sqrt(n)
//原式展开为n*(1-1/p1)*(1-1/p2)...(1-1/pk)
//等价于n = n/pi * (pi-1) 也等价于 n = n-(n/pi) (1<=i<=k)
long long phi(long long x)
{
long long ans = x;
for(long long i = 2;i <= sqrt(x);i++)
{
if(x % i == 0)
{
ans = ans/i * (i-1);
//分解质因数 p^ai
while(a % i == 0)
{
x /= i;
}
}
}
//最后剩下的可能是一个大于sqrt(x)的质数
if(x > 1) ans = ans/a * (x-1);
return ans;
}
线性求连续欧拉函数
引入一条新的性质:
若p不能整除n则p,n互质,根据积性函数的性质直接求解即可
令n = m*p,p为质数,则
又因为n%p == 0,m = n/p,所以n的质因子和m相同,也就是后面的累乘式相同
得证
有了这些性质支撑,就可以通过筛素数的方式来递推求解欧拉函数
void euler()
{
b[1] = 1;
p[1] = 1;
for(int i = 2;i <= n;i++)
{
if(!b[i])
{
//素数的phi(i) = i-1
prime[++cnt] = i;
p[i] = i-1;
}
for(int j = 1;j <= cnt && i*prime[j] <= n;j++)
{
b[i*prime[j]] = 1;
if(i % prime[j] == 0)
{
//i%p == 0 phi(i*p) = phi(i) * p
p[i*prime[j]] = p[i] * prime[j];
break;
}
//i%p != 0 利用积性函数性质 phi(i*p) = phi(i) * phi(p)
p[i*prime[j]] = p[i] * p[prime[j]];
}
}
}
欧拉定理(同余相关)
证明会在后面的介绍中讲到
扩展欧拉定理
证明很长,想了解可自行百度~