POJ 2407 Relatives

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

猜你喜欢

转载自blog.csdn.net/duanghaha/article/details/81228204