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

欧拉函数

时间:2018-02-25 17:31:37      阅读:141      评论:0      收藏:0      [点我收藏+]

标签:pre   AC   col   ++   ring   algorithm   getch   cst   out   

对正整数n,欧拉函数是小于n的正整数中与n互质的数的数目(φ(1)=1,φ(2)=1,φ(3)=2 ……)。

 

例如φ(8)=4,因为1,3,5,7均和8互质。

 

那么,这个定理有什么用呢???

来看一道题:

欧拉函数(phi)

题目描述:对正整数n,n 的欧拉函数(即φ(N))是少于或等于n 的数中与n 互质的数的数目。例如φ(8)=4,因为1,3,5,7 均和8 互质。

输入

一行一个整数N。

输出

一行一个整数φ(N)

样例输入

8

样例输出

4

哈哈哈,一道裸题,那么我们来仔细分析一下每一步:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#define N 10010
#define zxy(i , a , b) for(int i = a ; i <= b ; i ++)
#define yxz(i , a , b) for(int i = a ; i >= b ; i ++)
#define zxyzxy(i , a , b) for(int i = a ; i < b ; i ++)
#define yxzyxz(i , a , b) for(int i = a ; i > b ; i ++)
using namespace std;
typedef long long ll;
ll n,ans;
ll read() {
    ll ans = 0;
    char ch = getchar(),last =  ;
    while(ch < 0 || ch > 9)
        last = ch , ch = getchar();
    while(ch >= 0 && ch <= 9)
        ans = ans * 10 +ch - 0 , ch = getchar();
    if(last == -)
        ans =- ans;
    return ans;
}
void put(ll x) {
    if(x < 0) {
        putchar(-);
        x = -x;
    }
    if(x == 0) {
        putchar(0);
        return;
    }
    int q[100] , nn = 0;
    while(x)
        q[++ nn] = x % 10 , x /= 10;
    while(nn)
        putchar(0 + q[nn]), --nn;
}
int main() {
    //freopen("phi.in","r",stdin);
    //freopen("phi.out","w",stdout);
    n = read();
    ans = n;
    for(int i = 2 ; i * i <= n ; i ++)
    {
        if(n % i ==0)
            ans = ans / i * (i - 1);
        while(n % i == 0)
            n /= i;
    }
    if(n > 1)
        ans = ans / n * (n - 1);
    put(ans);
    return 0;
}

 

这里有个欧拉的公式:

 技术分享图片

即:

技术分享图片

 

 这个就是代码中的:

ans = ans / i * (i - 1);

先除后乘是为了防止溢出。

咱们从头来看这个代码:

i代表n的素因子。因为在后面的循环操作中,把n都变成了他的最小素因子,所以就可以把这个数的n次幂的数都可以删掉,就可以省时间。

i循环到根号n的原因是对于一个正整数n来说,在根号n到n的范围内有且只有一个n的素因子。

为什么呢?用反证法证明一下,如果有两个或两个以上的素因子在这段区间内的话,那么这两个因子的乘积就肯定会大于n,所以假设不成立。

那么这种循环到根号n的做法是既省码速,又省空间的。

因此,在最后要添加一个操作,就是把这个n再求一遍素因子个数。

因为如果假设n分解成的若干个质因数的幂的乘积中的一个单项式特别大的话,那么它就十分接近于n,所以它的指数就肯定是小于2的(上述已证根号n到n只有一个素因子),所以它的指数只能为1,就只要操作一次而不用像上面的用while来维护了。

最后的ans就是phi(n)的解了。

欧拉函数

标签:pre   AC   col   ++   ring   algorithm   getch   cst   out   

原文地址:https://www.cnblogs.com/Zhoier-Zxy/p/8469582.html

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