码迷,mamicode.com
首页 > 其他好文 > 详细

简谈欧拉函数

时间:2019-08-21 11:26:40      阅读:100      评论:0      收藏:0      [点我收藏+]

标签:normal   asc   init   typedef   stdin   undo   writer   stat   byte   

 

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.求解单个值的欧拉函数

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;
}

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

 

 

 

 

 

简谈欧拉函数

标签:normal   asc   init   typedef   stdin   undo   writer   stat   byte   

原文地址:https://www.cnblogs.com/cautx/p/11387422.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!