Akvicor
Akvicor
发布于 2019-08-13 / 49 阅读
0
0

欧拉函数证明

给定任意正整数,那么在小于等于的所有正整数之中,有多少个与构成互质关系?

计算这个值的方法就叫做欧拉函数表示:在之中,与n构成互质关系的数的数量。

分析

情况一

如果,则。因为1与任何数(包括自身)都构成互质关系

情况二

如果是质数,则。因为质数与小于它的每一个数,都构成互质关系。比如都构成互质关系。

情况三

如果是质数的某一个次方,即为质数,为大于等于的整数),则

比如

这是因为只有当一个数不包含质数,才有可能与互质。而包含质数的数一共有个。

,把他们去除,剩下的就是与互质的数。

上面的式子还可以写成下面的形式:

可以看出,上面的第二种情况是时的特例

情况四

如果n可以分解成两个互质的整数之积:

则:

即积的欧拉函数等于各个因子的欧拉函数之积。比如

对于素数,对于两个素数

欧拉函数是积性函数,但不是完全积性函数

欧拉函数的积性

互质,则

由“互质”可知无公因数,所以:

其中的质因数,的质因数,而无公因数。

所以互不相同,所以均为的质因数且为的质因数的全集。

所以

所以

以上部分涉及到“中国剩余定理”

情况五

因为任意一个大于1的正整数,都可以写成一系列质数的积。(分解质因数)

根据结论四,得到

再根据结论三,得到

也就等于

结论

比如

只在时成立。

对于一个正整数的素数幂分解

除了都是偶数

为正整数,

欧拉函数

根据性质二,我们可以在的时间复杂度内求出一个数的欧拉函数值。

//直接求解欧拉函数  
int euler(int n) { //返回euler(n)   
    int res = n, a = n;
    for (int i = 2; i * i <= a; 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;
}

欧拉函数线性筛

如果要求以内的所有数的欧拉函数

const int MAXN = 1e6;
//欧拉线性筛:在线性时间内筛素数的同时求出所有数的欧拉函数
int tot;
int phi[MAXN]; //保存各个数字的欧拉函数
int prime[MAXN]; //按顺序保存素数
bool mark[MAXN]; //判断是否是素数
void get_phi(int N){
    phi[1] = 1;
    for(int i = 2; i <= MAXN; i++){ //相当于分解质因数的逆过程
        if(!mark[i]){
            prime[++tot] = i;
            phi[i] = i-1;
        }
        for(int j = 1; j <= tot; j++){
            if(i * prime[j] > N) break;
            mark[i * prime[j]] = 1; //确定i*prime[j]不是素数
            if(i % prime[j] == 0){ //判断prime[j] 是否为 i的约数
                phi[i * prime[j]] = phi[i] * prime[j];
                break;
            }
            else{ //prime[j] - 1 就是 phi[prime[j]],利用了欧拉函数的积性
                phi[i * prime[j]] = phi[i] * (prime[j] - 1);
            }
        }
    }
}


评论