欧拉函数及其扩展


欧拉函数

 

     对正整数n,欧拉函数是少于或等于n的数中与n互质的数的数目。例如euler(8)=4,因为1,3,5,7均和8互质。
     Euler函数表达通式:euler(x)=x(1-1/p1)(1-1/p2)(1-1/p3)(1-1/p4)…(1-1/pn),其中p1,p2……pn为x的所有素因数,x是不为0的整数。euler(1)=1(唯一和1互质的数就是1本身)。 
     欧拉公式的延伸:一个数的所有质因子之和是euler(n)*n/2。

     那么如何变成实现欧拉函数呢?下面通过两种不同的方法来实现。第一种方法是直接根据定义来实现,同时第一种方法也是第二种筛法的基础,当好好理解。



求单个数的欧拉函数

题意:给你一个数n,n很大(n<=100000000),但是题目中的测试数据不是很多,这样的话直接用求单个欧拉函数值的方法求解,如果用下面第二种方法打个表的话是行不通的,因为n的值太大不适合开设数组,所以这时应该直接求n的欧拉函数值。


//直接求解欧拉函数
int euler(int n){ //返回euler(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;
}

//筛选法打欧拉函数表 
#define Max 1000001
int euler[Max];
void Init(){ 
     euler[1]=1;
     for(int i=2;i<Max;i++)
       euler[i]=i;
     for(int i=2;i<Max;i++)
        if(euler[i]==i)
           for(int j=i;j<Max;j+=i)
              euler[j]=euler[j]/i*(i-1);//先进行除法是为了防止中间数据的溢出 
}


最后推荐两道题

1、foj 1607 Greedy division http://acm.fzu.edu.cn/problem.php?pid=1607


Problem 1607 Greedy division

Accept: 477    Submit: 1698
Time Limit: 1000 mSec    Memory Limit : 32768 KB

 Problem Description

Oaiei has inherited a large sum of wealth recently; this treasure has n pieces of golden coins. Unfortunately, oaiei can not own this wealth alone, and he must divide this wealth into m parts (m>1). He can only get one of the m parts and the m parts have equal coins. Oaiei is not happy for only getting one part of the wealth. He would like to know there are how many ways he can divide the wealth into m parts and he wants as many golden coins as possible. This is your question, can you help him?

 Input

There are multiply tests, and that will be 500000. For each test, the first line is a positive integer N(2 <= N <= 1000000), N indicates the total number of golden coins in the wealth.

 Output

For each test, you should output two integer X and Y, X is the number of ways he can divide the wealth into m parts where m is large than one, Y is the number of golden coins that he can get from the wealth.

 Sample Input

568

 Sample Output

1 13 33 4

 Hint

There are huge tests, so you should refine your algorithm.


题目大意:给你一个数n,求出n的因数的个数(1除外),以及n/(n最小的非1因数)。

My  AC  code(欧拉函数的变形):

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
#define MAXN 1000010
using namespace std;
int phi[MAXN];//phi[n]表示n的不包括1的因子总个数
int min_yue[MAXN];
void init_euler()
{
	phi[1]=1;//可省略
	min_yue[1]=1;//可省略
	for(int i=2;i<MAXN;i++)
	{
		for(int j=i;j<MAXN;j+=i)
		{
			phi[j]++;
			if(min_yue[j]==0)
				min_yue[j]=i;
		}
	}
}
int main()
{
	int n;
	init_euler();
	while(scanf("%d",&n)!=EOF)
	{
		printf("%d %d\n",phi[n],n/min_yue[n]);
	}
	return 0;
 } 


zju 3286  Very Simple Counting http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=3625



Very Simple Counting Time Limit: 1 Second       Memory Limit: 32768 KB

Let f(n) be the number of factors of integer n.

Your task is to count the number of i(1 <= i < n) that makes f(i) = f(n).

Input

One n per line (1 < n <= 1000000).

There are 10000 lines at most.

Output

For each n, output counting result in one line.

Sample Input

4
5

Sample Output

0
2

Hint

f(1) = 1, f(2) = f(3) = f(5) = 2, f(4) = 3.



注意:此题必须先打表,否则会超时。。。


AC code:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
#define MAXN 1000010
using namespace std;
int phi[MAXN],ans[MAXN],cnt[MAXN];
int min_yue[MAXN];
void init_euler()
{
	//phi[1]=1;
	min_yue[1]=1;
	for(int i=2;i<MAXN;i++)
	{
		for(int j=i;j<MAXN;j+=i)
		{
			phi[j]++;
			if(min_yue[j]==0)
				min_yue[j]=i;
		}
	}
}
int main()
{
	int n,i;
	init_euler();
	for(i=1;i<MAXN;i++)
	{
		cnt[phi[i]]++;
		ans[i]=cnt[phi[i]]-1;
	}
	while(scanf("%d",&n)!=EOF)
	{
		printf("%d\n",ans[n]);
	}
	return 0;
 } 





你可能感兴趣的:(算法,ACM)