欧拉函数


一个数的欧拉函数是指不超过这个数且与此数互质的正整数的个数。

1、如果n是质数,则φ(n) = n - 1

2、如果n为两个互质的数a,b的乘积,则φ(a*b) = φ(a) * φ(b)

a*b互质的数,只能是既与a互质(φ(a)),又与b互质(φ(b)),所以一共有φ(a) * φ(b)

3、如果n为某一个质数p的幂次p^a,则φ(p^a) = (p-1)*p^(a-1)

[1,p^a-1]范围内能被p整除的数一共有p^(a-1)-1个数,区间总数是p^a-1个,所以φ(p^a) = p^a-p^(a-1) = (p-1)*p^(a-1)

 

那么对于任意数求它的欧拉函数。

n = p1^k1 * p2^k2 * p3^k3*....*pn^kn

φ(n)  = φ(p1^k1) * φ(p2^k2)*...*φ(pn^kn)

  =  (p1-1)*p1^(k1-1)*(p2-1)*p2^(k2-1)*....

      =  p1^k1 * p2^k2 * p3^k3*....*pn^kn * (1-1/p1)*(1-1/p2)*...*(1-1/pn)

      =  n * (1-1/p1)*(1-1/p2)*...*(1-1/pn)

 

1、单个欧拉函数的计算  POJ 2407

Phi(n) = (pi-1) * pi^(a-1)

求出每一个质因子和幂次,由公式计算得到。


LL cal( LL x )
{
    LL ans = 1;
    for( int i = 2; i*i <= x; i++ )
    {
        if ( x % i == 0) //找到一个质因子
        {
            ans*=i-1;
            x /= i;
            while( x % i == 0 )
            {
                ans *= i;
                x /= i;
            }
        }
    }
    if ( x > 1 ) ans*=(x-1);
    return ans;
}


 

2、欧拉函数线性筛( NlogN )  POJ 3090


找到n的最小质因数k  phi( p ^a ) = (p-1)* p^( a - 1 )

如果n只能整除kphi(n) = phi( n/k )*(k-1)

否则 phi(n) = phi(n/k)*k  

 

void getphi(int n)
{
    rep(i,1,n) mindiv[i] = i; //记录i的最小质因数
    for(int i = 2; i*i <= n; i++)
        if ( mindiv[i] == i )
        {
            for(int j = i*i; j <= n; j+=i) mindiv[j] = i;
        }
    phi[1] = 1;
    rep(i,2,n)
    {
        phi[i] = phi[i/mindiv[i]];
        if ( ( i / mindiv[i] ) % mindiv[i] == 0 ) phi[i] *= mindiv[i]; //还可以再除
        else phi[i] *= ( mindiv[i] - 1 );
    }
}


 3、欧拉筛O(N)

int prime[maxn/5];
int f[maxn];
bool isprime[maxn];

void init()
{
	int count = 0;
	Clean(isprime,true);
	for( int i = 2; i <= 5000000; i++ )
	{
		if ( isprime[i] )
		{
			prime[++count] = i;
			f[i] = i - 1;
		}

			for( int j = 1; j <= count; j++ )
			{
				if ( i * prime[j] > maxn-5 ) break;
				isprime[ i * prime[j] ] = false;
				if ( i % prime[j] )
					f[ i * prime[j] ] = (prime[j]-1) * f[i];
				else
				{
					f[ i * prime[j] ] = (prime[j]) * f[i];
					break;
				}
			}				
		
	}	
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值