Relatives
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 10159 | Accepted: 4899 |
Description
Given n, a positive integer, how many positive integers less than n are relatively prime to n? Two integers a and b are relatively prime if there are no integers x > 1, y > 0, z > 0 such that a = xy and b = xz.
Input
There are several test cases. For each test case, standard input contains a line with n <= 1,000,000,000. A line containing 0 follows the last case.
Output
For each test case there should be single line of output answering the question posed above.
Sample Input
7 12 0
Sample Output
6 4
Source
题型:数论
题意:求N有多少<=N与N互质的数。
分析:
欧拉函数的概念:对正整数n,欧拉函数是少于或等于n的数中与n互质的数的数目,又称φ函数。
例如φ(8)=4,因为1,3,5,7均和8互质。
通式:φ(x)=x(1-1/p1)(1-1/p2)(1-1/p3)(1-1/p4)…..(1-1/pn),其中p1, p2……pn为x的所有质因数,x是不为0的整数。φ(1)=1(唯一和1互质的数就是1本身)
这样题目就很清楚了,就是求φ(N)。
根据通式,我们可以先求出N的所有质因子,然后再套用公式。可以将式子先转化一下
1-1 / pn =(pn-1)/ pn
这样就避免用double了,但是注意要用__int64,用int返WA。。。
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#define LL long long
using namespace std;
const int maxn=123456;
int cnt;
LL facs[maxn];
void find_fac(LL n){
cnt=0;
for(int i=2;i*i<=n;i+=2){
while(!(n%i))
n/=i,facs[cnt++]=i;
if(i==2) --i;
}
if(n>1) facs[cnt++]=n;
}
int main(){
LL n;
while(scanf("%I64d",&n)&&n){
find_fac(n);
LL ans;
ans=n*(facs[0]-1)/facs[0];
for(int i=1;i<cnt;i++){
if(facs[i]!=facs[i-1]){
ans=ans*(LL)(facs[i]-1)/facs[i];
}
}
printf("%I64d\n",ans);
}
return 0;
}