简谈欧拉函数

 

START

参考博客:https://blog.csdn.net/qq_39922639/article/details/77511761

欧拉函数是积性函数的一种,所谓积性函数是指满足,gcd(a,b)&&ƒ(a*b)=ƒ(a)*ƒ(b)的函数,特别的,若gcd(a,b)!=1但是ƒ(a*b)=ƒ(a)*ƒ(b)仍然满足,我们称之为完全积性函数。

定义:

记欧拉函数φ(n)表示从{1,2,3......n}中和n互质的数的个数,即:φ(n) =

性质:

1.φ(n) = n-1 (n为质数) :因为在1到n这n个数中只有n不与n互质,所以是n-1。

2.φ(n) < n-1 (n不是质数)。

3.当p为质数时,φ(pk)=pk-pk-1=pk-1×(p-1)=pk-1×φ(p)。

4.

5.

6.n>1时,1,2,3......n中与n互质的整数和为n*φ(n)/2。

 

扩展性质:

如何求解欧拉函数:

1.求解单个值的欧拉函数

int ph(int x)
{
    int res=x,a=x;
    for(int i=2;i*i<=x;i++)
    {
        if(a%i==0)
        {
            res=res/i*(i-1);
            while(a%i==0) a/=i;
        }
    }
    if(a>1) res=res/a*(a-1);
    return res;
}

 

2.线性筛预处理欧拉函数

bool vis[1000005];
int tot=0, pri[1000005], phi[1000005];
void Get_phi(int N){
    phi[1] = 1;
    for(int i=2; i<=N; ++i){
        if(!vis[i]){
            pri[++tot] = i;
            phi[i] = i-1;
        }
        for(int j=1,x; j<=tot&&(x=i*pri[j])<=N; ++j){
            vis[x] = true;
            if(i%pri[j] == 0){
                phi[x] = phi[i]*pri[j];
                break;
            }
            else phi[x] = phi[i]*phi[pri[j]];
        }
    }
}

模板题:POJ 2407

#include<cstdio>
#include<cstring>
using namespace std ;
typedef long long ll;
bool u[50005];
ll su[50005],num;
void olas()
{
    num=0; 
    memset(u,true,sizeof(u));
    for(int i=2; i<=50000; i++)
    {
        if(u[i])    su[++num]=i;
        for(int j=1; j<=num; j++)
        {
            if(su[j]*i>50000)    break;
            u[i*su[j]]=false;
            if(i%su[j]==0)    break;
        }
    }
}
ll phi(ll x)
{
    ll i,j,k;
    ll ans=1;
    for( i=1; i<=num; i++)
    {
        if(x%su[i]==0)
        {
            j=0;
            while(x%su[i]==0)
            {
                ++j;
                x/=su[i];
            }
            for( k=1; k<j; k++)
            {
                ans=ans*su[i]%1000000007ll;
                //cout<<"1"<<" "<<ans<<endl;
            }
            ans=ans*(su[i]-1)%1000000007ll;
            //cout<<"2"<<" "<<ans<<endl;
            if(x==1)    break;
        }
    }
    if(x>1)    ans=ans*(x-1)%1000000007ll;
    //cout<<"3"<<' '<<ans<<endl;
    return ans;
}
int main()
{
    //freopen("input.txt","r",stdin);
    ll n;
    olas();
    while(~scanf("%lld",&n)&&n)
    {
        printf("%d\n",(int)phi(n));
    }
}
View Code

 

END

 

 

 

 

 

posted on 2019-08-21 10:53  Caution_X  阅读(176)  评论(0编辑  收藏  举报

导航