欧拉函数
欧拉函数是少于或等于n的数中与n互质的数的数目。
欧拉函数的性质:它在整数n上的值等于对n进行素因子分解后,所有的素数幂上的欧拉函数之积。
就是对于一个正整数n,小于n且和n互质的正整数(包括1)的个数,记作φ(n) 。
欧拉函数的通式:φ(n)=n*(1-1/p1)(1-1/p2)(1-1/p3)*(1-1/p4)……(1-1/pn)
其中p1, p2……pn为n的所有质因数,n是不为0的整数。φ(1)=1(唯一和1互质的数就是1本身)。
单次询问欧拉函数
ll euler(ll n)
{
ll t=n;
for(int i=2;i*i<=n;i++)
{
if(n%i==0) //i为质因子
{
t=t/i*(i-1); //==t*(1-1/i)前面那样写是为了防止溢出
while(n%i==0) //把该质因子都除完
{
n/=i;
}
}
}
if(n>1) //这是为了如果n还为素数,加一个这个
t=t/n*(n-1);
return t;
}
欧拉筛法实现(求出多个)
欧拉函数特性:
1 若 a 为质数,phi[a]=a-1;
2 若 a 为质数,b % a=0,phi[a * b] = phi[b] * a
3 若 a,b 互质,phi [a * b]=phi[a] * phi[b](当 a 为质数时,if b % a!=0 ,phi[a*b]= phi[a] * phi[b])
const int maxn=10000;
int pd[maxn],phi[maxn],p[maxn],ssnum;//pd为判断n是否为素数pd[]==0为素数,p为素数筛里面全为素数
//phi[]为欧拉函数答案,ssnum为当前素数个数
void Oula()
{
phi[1]=1;
ssnum = 0;
for(int i = 2; i<=maxn; i++)
{
if(!pd[i])//如果i为素数
{
p[ssnum++] = i; //将i存入素数数组p[]中
phi[i]= i-1; //特性1 若i为质数,phi[i]=i-1;
}
for(int j = 0;j<ssnum && i*p[j]<maxn;j++) //素数筛,筛去i*p[j]
{
pd[i*p[j]]= 1;//素数的乘积都标记为非素数
if(i%p[j]==0)
{
phi[i*p[j]]=phi[i]*p[j]; //特性2 若 b%a=0,phi[a*b]=phi[b]*a
break;
}
else
{
phi[i*p[j]]=phi[i]*(p[j]-1); //特性3 若 a,b 互质,phi[a*b]=phi[a]*phi[b]
//p[j]-1就是phi[p[j]] 特性1
}
}
}
}