找新朋友 hdu 1286

http://acm.hdu.edu.cn/showproblem.php?pid=1286

分析:与会长的编号(N)有大于1的公约数则为老朋友,让你求新朋友的个数。那么新朋友肯定是与会长的编号(N)互质的数了。

注意:一般做法都会超时。这时候就需要用到欧拉函数了。

欧拉函数:
        (求出一个数n与1~n之间互质的个数):找到n的一个质因子i,那么1~n中与n的公约数是i的倍数的概率pi = 1/i,那么与n的公约数不是i的倍数(这些数可能就是与n互质的数)概率为1-pi,即(i-1)/i;那么当我们找到n所有的质因子时,1~n之间与n互质的概率就是所有(1-pi)的乘积,那么与n互质的个数就是: Eular(n)=n*(1-p1)*(1-p2)....(1-pi);

        简单来说,对正整数n,欧拉函数是少于或等于n的数中与n互质的数的数目。例如Euler(8)=4,因为1,3,5,7均和8互质。

欧拉函数延伸:一个数的所有质因子之和是euler(n)*n/2。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <queue>
using namespace std;
#define maxn 32768
#define oo 0x3f3f3f3f

int euler(int 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;
}

int main()
{
    int T, n;

    scanf("%d", &T);


    while(T --)
    {
        scanf("%d", &n);
        printf("%d
", euler(n));
    }

    return 0;
}
View Code
原文地址:https://www.cnblogs.com/daydayupacm/p/5731480.html