Relatives
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 16322 | Accepted: 8272 |
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
题意:小于n的数中有多少数与n互质。
这道题目有两种写法,一种是直接用欧拉函数:
#include<iostream>
#include<algorithm>
#include<math.h>
using namespace std;
typedef long long ll;
#define maxn 100005
ll re[maxn];
int k;
ll gcd(ll a,ll b) {
return b?gcd(b,a%b):a;
}
ll lcm(ll a,ll b)
{
return a/gcd(a,b)*b;
}
ll primefactor(ll n)
{
k=0;
ll ans=n;
for(int i=2;i<=(ll)sqrt(n+0.5);i++)
{
if(n%i==0)
{
ans=ans/i*(i-1);
while(n%i==0) n/=i;
}
}
if(n!=1)
{
ans=ans/n*(n-1);
}
return ans;
}
int main()
{
ll n;
while(cin>>n&&n)
{
cout<<primefactor(n)<<endl;
}
return 0;
}
第二种方法:质因数分解+二进制状态枚举+容斥原理:
把n质因数分解,将质因数储存到数组中去,然后从1-n-1进行容斥。
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
#define maxn 100005
ll re[maxn];
int k;
ll gcd(ll a,ll b) {
return b?gcd(b,a%b):a;
}
ll lcm(ll a,ll b)
{
return a/gcd(a,b)*b;
}
void primefactor(ll n)
{
k=0;
for(int i=2;i*i<=n;i++)
{
while(n%i==0)
{
re[k++]=i;
n/=i;
}
}
if(n!=1)
{
re[k++]=n;
}
}
int main()
{
ll n;
while(cin>>n&&n)
{
ll d=n;
primefactor(n);
ll ans=0;
for(int i=1;i<(1 << k);i++)
{
ll cnt=0;
ll temp=1;
for(int j=0;j<k;j++)
{
if(i >> j & 1)
{
cnt++;
temp=lcm(temp,re[j]);
}
}
if(cnt&1) ans+=(d-1)/temp;
else ans-=(d-1)/temp;
}
cout<<d-ans-1<<endl;
}
return 0;
}