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